Dynamic matrix inside struct, C programming - c

I need help. I want to learn how to create and use dynamic matrix which is element of structure, I want to fill matrix with zeros (0) and print it out, I tried many ways but no luck. Here is the code
#include <stdio.h>
#include <stdlib.h>
typedef struct matrica
{
int **mat;
int dim; //this is dimension of squared matrix
}MATRICA;
void form_matrix(MATRICA *matrica);
int main()
{
MATRICA matrix;
form_matrix(&matrix);
return 0;
}
void form_matrix(MATRICA *matrica)
{
int i, j;
MATRICA *br;
do
{
printf("Size of matrix ");
scanf("%d", &br->dim);
}while(br->dim < 4 || br->dim > 6);
matrica->mat = (int **) calloc(br->dim, sizeof(int *));
for(i = 0; i < br->dim; i++)
{
matrica->mat[i] = (int *) calloc(br->dim, sizeof(int));
for(j = 0; j < br->dim; j++)
{
matrica->mat[i][j] = 0;
}
}
for(i = 0; i < br->dim; i++)
for(j = 0; j < br->dim; j++)
printf("%d ", matrica->mat[i][j]);
}
what am I doing wrong, my loop inside function goes only once, can someone explain to me why?

Your program exhibits undefined behavior because you are dereferencing an uninitialized pointer br. You don't need it, you simply need a variable to store your dimension input.
int i, j, dim;
do
{
printf("Size of matrix ");
if (scanf("%d", &dim) != 1) {
printf("scan failed\n");
exit(EXIT_FAILURE);
}
}while(dim < 4 || dim > 6);
matrica->dim = dim;
/* ... replace all instances of br->dim with dim */

Related

How to pass and return two-dimensional array from function in c

I am relatively new to c, and I still have not been able to find a good way of passing and returning a multi-dimensional array from a function. I found the following code, however it doesn't seem like a good way to do things because it passes the array and then to use it, it creates a duplicate with the malloc function. Is there a way to do it without the copying and malloc function, or a better way to pass and return an 2d array from a function in c in general? Thanks.
#include <stdio.h>
#include <stdlib.h>
int **matrix_sum(int matrix1[][3], int matrix2[][3]){
int i, j;
int **matrix3;
matrix3 = malloc(sizeof(int*) * 3);
for(i = 0; i < 3; i++) {
matrix3[i] = malloc(sizeof(int*) * 3);
}
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return matrix3;
}
int main(){
int x[3][3], y[3][3];
int **a;
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
a = matrix_sum(x,y); //asigning
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
//free the memory
for(i = 0; i < 3; i++) {
free(a[i]);
}
free(a);
return 0;
}
The array are not copied for agurments. Just pointers to the first elements of them (int[3]) are passed.
To avoid malloc(), you should add another argument to specify the array where the result should be stored.
#include <stdio.h>
void matrix_sum(int matrix3[][3], int matrix1[][3], int matrix2[][3]){
int i, j;
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
}
int main(){
int x[3][3], y[3][3], a[3][3];
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
matrix_sum(a,x,y);
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
return 0;
}
An array can be declared and used through a reference (pointer)
for instance
char array[] = {'h','e','l', 'l', 'o', '\0'};
char *pointer = array;
the way pointers work can be understood by calling sizeof() on a given type
printf("char:%d\nchar_pointer: %d\n", sizeof(char), sizeof(char*));
which results in the following output.
char:1
char_pointer: 4
these results mean that even though a char has 1byte, its pointer needs 4 in order to be stored in memory thus, they are not the same type.
now in order to pass an array as an argument to a function you have many options
void function1(array[4])
{
//this function can receive an array of four elements and only four elements;
//these types of functions are useful if the algorithm inside the function only works
//with a given size. e.g. matrix multiplication
}
//or
void function2(char array[], int size)
{
//this function can receive an array of elements of unknown size, but you can
//circumvent this by also giving the second argument, the size.
int i;
for(i = 0; i <= size; i++)
{
printf("%c", array[i]);
}
}
In order to use or call any of these functions you could pass the array or a pointer to the array
function2(array, 5);
function2(pointer, 5);
//these results are the same
The same applies to a multidimensional array
void function3(char** multi_dim_array, array_size_first_dim, array_size_second_dim);
//and you can call it by using the same syntax as before;
void main(int argc, char[] argv*)
{
char** multi_dim = malloc(sizeof(char*) * 3);
int i;
for(i = 0; i<=3 ; i++)
{
multi_dim[i] = malloc(sizeof(char) * 4);
}
function3(multi_dim, 3,4);
}
if you want to return a multidimensional array you can just return a pointer
char **malloc_2d_array(int dim1, int dim2)
{
char ** array = malloc(sizeof(char*)*dim1);
int i;
for(i = 0; i<=dim2; i++)
{
array[i] = malloc(sizeof(char) * dim2);
}
return array;
}
as a final note, the reason the code you found, copies the array, is because of functional programming(a way of programming if you will) where a function call cant modify its input, thus it will always create a new value;
First of all this is not gonna be a technical explanation. I am just gonna try and explain what works not why.
For passing a multidimensional array you can use either an array with a defined size as you did in your example code:
void matrix_sum(int matrix3[][3])
Or if you don't want to use a defined size and want to take care of memory usage you can use a pointer to a pointer. For this case you also need to pass the size (unless you are passing NULL-terminated strings). Like this:
void matrix_sum(int **matrix, int size)
BUT for this case you can't call the function with a "normal" array. You need to use a pointer to a pointer or a pointer to an array.
int **matrix;
// make sure to allocate enough memory for this before initializing.
or:
int *matrix[];
For returning an array you can just return a pointer to a pointer like you did in your code example.
But you don't need to return an array, because if you change a value in an array, (in a different function) the value will stay changed in every other function.
A short example for this:
#include <stdio.h>
void put_zeros(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
matrix[i][j] = 0;
j++;
}
i++;
}
}
void print_matrix(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
printf("%d ", matrix[i][j]);
j++;
}
printf("\n");
i++;
}
}
int main(void)
{
int matrix_first[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
print_matrix(matrix_first);
put_zeros(matrix_first);
print_matrix(matrix_first);
}
This will print "1 2 3 4 5 6 7 8 9" because that's the first value we assigned.
After calling put_zeros it will contain and print "0 0 0 0 0 0 0 0 0" without the put_zeros returning the array.
1 2 3
4 5 6
7 8 9
0 0 0
0 0 0
0 0 0

initialization of arrays while operating with mallocs

Given the following piece of code, I don't understand why do we have to initialize every single row of the matrix when we have already created enough space in the stack.
#include <stdio.h>
#include <stdlib.h>
main() {
int **w;
int i, j;
int m, n;
printf("Number of rows in the matrix: ");
scanf("%d", &m);
printf("Number of columns in the matrix: ");
scanf("%d", &n);
w = (int **)malloc(m * n * sizeof(int));
for (i = 0; i < m; i++)
w[i] = (int *)malloc(n * sizeof(int));
for (i = 0; i < m; i++)
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: ", i + 1, j + 1);
scanf("%d", &w[i][j]);
}
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("Element [%d][%d]: %d\n", i + 1, j + 1, w[i][j]);
}
There are many issues in your code:
space is not allocated on the stack, but from the heap.
in both cases, memory allocated for the objects is uninitialized, which means it is not initialized to anything in particular and can have any value whatsoever. Relying on any particular contents is undefined behavior.
the matrix dimensions and all the matrix elements are read from standard input with scanf(). Yet you do not check for scanf() failure to convert integers from the characters read from stdin, so any invalid or missing input is going to cause undefined behavior at some point in the program.
your matrix is actually structured as an array of pointers to arrays of int, which is fine, but inconsistent with the size arguments used to allocate the first array: w = (int **)malloc(m * n * sizeof(int)); should be
w = malloc(m * sizeof(*w));
you could easily get objects pre-initialized to 0 by using calloc() instead of malloc():
for (i = 0; i < m; i++)
w[i] = calloc(n, sizeof(int));
you should also check for malloc() failure and exit with an appropriate diagnostic message.
main() is an obsolete prototype for the main function. You should either use int main(), int main(void) or int main(int argc, char *argv[])...
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int get_int(void) {
int n;
if (scanf("%d", &n) != 1) {
printf("invalid input\n");
exit(EXIT_FAILURE);
}
return n;
}
void xalloc(size_t size) {
void *p = calloc(size, 1);
if (p == NULL) {
printf("out of memory for %zu bytes\n", size);
exit(EXIT_FAILURE);
}
return p;
}
int main() {
int **w;
int i, j;
int m, n;
printf("Number of rows in the matrix: ");
m = get_int();
printf("Number of columns in the matrix: ");
n = get_int();
w = xalloc(m * sizeof(*w));
for (i = 0; i < m; i++) {
w[i] = xalloc(n * sizeof(int));
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: ", i + 1, j + 1);
w[i][j] = get_int();
}
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: %d\n", i + 1, j + 1, w[i][j]);
}
}
for (i = 0; i < m; i++) {
free(w[i]);
}
free(w);
return 0;
}

What's wrong with this initialization? Why can't I succeed when I try to initialize a graph using the initialization function

using VS,C language.
I try to initialization a Graph structure by a initialize fuction
#include<stdio.h>
#define maxint 1000
#define mvnum 100
typedef struct
{
int vexs[mvnum];
int edges[mvnum][mvnum];
int n, e;
}MGraph;
void creatUDN(MGraph *G) {
G = (MGraph*)malloc(sizeof(MGraph));
int i, j, k, w;
scanf_s("%d", &(G->n));
scanf_s("%d", &(G->e));
for (i = 0; i < G->n; i++)
scanf_s("%d", &(G->vexs[i]));
for (i = 0; i < G->n; ++i)
for (j = 0; j < G->n; ++j)
G->edges[i][j] = maxint;
for (k = 0; k < G->e; k++)
{
scanf_s("%d %d %d", &i, &j, &w);
G->edges[i-1][j-1] = w;
}
for (i = 0; i < G->n; ++i)
{
for (j = 0; j <G->n; ++j)
printf("%d\t", G->edges[i][j]);
printf("\n");
}
}
this is main function
int main()
{
MGraph *g;
g=(MGraph*)malloc(sizeof(MGraph));
creatUDN(g);
**printf("%d", g->e);**
}
It shows that g still a Nullpointer after initialize.
why?
Remove the assignment to G in creatUDN.
G = (MGraph*)malloc(sizeof(MGraph));
Now your code will work.
You correctly allocated this data structure in main and passed the pointer to creatUDN, but then for some reason you allocated it again in creatUDN so the data structure you allocated in main remains unchanged.
The other way you can do this is to return the allocated data structure from creatUDN. That would look like this
MGraph *creatUDN() {
G = (MGraph*)malloc(sizeof(MGraph));
...
return G;
}
int main()
{
MGraph *g = creatUDN();
printf("%d", g->e);
}
You seem to have written something that's half way between these two methods.

Matrix columns zeroing, C language

I need to make a little project but I completely don't know how. Im giving matrix A of size n, and it have to return me matrix B which is matrix A with zeroed first and penultimate column. All I did is
#include<stdio.h>
#include<math.h>
int main()
{
int i,n,j,;
int tab[n][n];
printf("Size of matrix:");
scanf("%d",&n);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
printf("A[%d][%d]=",i,j);
scanf("%lf",&tab[i][j]);
}
printf("Data:");
printf("Matrix A[%d][%d]",n,m);
}
Which I think should let me to type my matrix. What I should do next? Please help me.
There are a lot of errors in your code, the variable m is not declared, the double array is declared with n non-initialized. As the size of matrix is only known at runtime (entered by user), you need to use dynamic memory allocation functions to allocate memory for your matrix.
Try this code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, j, n;
printf("Size of matrix: ");
scanf("%d", &n);
int *tab = (int*)malloc(sizeof(int)*n*n);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
printf("A[%d][%d]=",i,j);
scanf("%d",(tab+i*n+j));
}
}
for (i = 0; i < n; i++)
{
*(tab+i*n) = 0;
*(tab+i*n+n-2) = 0;
}
//Print tab
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", *(tab+i*n+j));
}
printf("\n");
}
return 0;
}

How to initialize, create matrix and then print with using structure

I want to create 2D array using structure and read from user, then display it. But I can't find out what's wrong with this.
/Sorry guys.First, I want it to read a matrix elements from user, then I want to display whole matrix. But it doesn't print properly, it prints address of elements. Why is it printing address, not value? /
Here is my code:
#include <stdio.h>
struct Matrix {
int n,m;
int a[100][100];
}array;
int main() {
struct Matrix *p;
int i,j;
p = malloc(sizeof(array));
scanf("%d%d", &p->n, &p->m);
for (i = 0;i < p->n;i++)
for (j = 0;j < p->m;j++)
scanf("%d", p->a[i][j]);
for (i = 0;i < p->n;i++){
for (j = 0;j < p->m;j++)
printf("%d ", (p->a[i][j]));
printf("\n");
}
}
Change scanf("%d", p->a[i][j]); to scanf("%d", &p->a[i][j]);. Better to check the result of scanf() to ensure code received the expected data.
if (scanf("%d", &p->a[i][j]) != 1) Oops();
Enable all warning on your compiler. This problem popped up right away.
#include <stdio.h>
struct Matrix {
int n, m;
int a[100][100];
} array;
int main() {
struct Matrix *p;
int i, j;
p = malloc(sizeof(array));
scanf("%d%d", &p->n, &p->m);
for (i = 0; i < p->n; i++)
for (j = 0; j < p->m; j++) {
// scanf("%d", p->a[i][j]);
scanf("%d", &p->a[i][j]);
}
for (i = 0; i < p->n; i++) {
for (j = 0; j < p->m; j++)
printf("%d ", (p->a[i][j]));
printf("\n");
}
}

Resources