The program you want should be like this:
#include <stdio.h>
#include <stdlib.h>
typedef struct matriz mat;
struct matriz {
int lin;
int col;
int *arr;
};
mat* cria(int lin, int col) {
mat *m = malloc(sizeof(mat));
m->lin = lin;
m->col = col;
m->arr = malloc(lin * col * sizeof(int));
return m;
}
void destroi(mat *m) {
if (m == NULL) return;
free(m->arr);
free(m);
}
int ler_elemento(mat *m, int i, int j) {
return m[i * m->col + j];
}
int definir_elemento(mat *m, int i, int j, int valor) {
m[i * m->col + j] = valor;
}
void exibe(mat *m) {
for (int i = 0; i < m->lin; i++) {
for (int j = 0; j < m->col; j++) {
printf("%3d ", ler_elemento(m, i, j));
}
printf("\n");
}
}
int main() {
mat *m;
m = cria(2, 2);
definir_elemento(m, 0, 0, 24);
definir_elemento(m, 0, 1, 16);
definir_elemento(m, 1, 0, 13);
definir_elemento(m, 1, 1, 56);
exibe(m);
destroi(m);
return 0;
}
Note that I created the functions ler_elemento
and definir_elemento
to centralize, abstract and encapsulate the logic of accessing the elements in the correct positions. This way, the other parts of the code don’t have to worry about the more complicated details of how to find the correct position in the array of matrix elements and won’t even have to worry about knowing the structure mat
has an array inside. With that, if later you want to change the way the structure mat
organises your data, only functions ler_elemento
, definir_elemento
and cria
will need to be changed, which avoids cascading changes, where changing a small detail would force the need to promote major changes in the whole code.
I also added a function to de-locate the mat
. It is good practice to always dislocate what you allocate, and therefore, whenever you have a function that creates something through dynamic memory allocation, you should already immediately have the hand function that dislodges that same thing.
As to the sizeof(m->arr)
, That will give you the size of the pointer m->arr
instead of the matrix size. Note that arr
is the type int *
, and therefore sizeof(m->arr)
is the same as sizeof(int *)
. The result is 4 because an integer pointer occupies 4 bytes on your computer, no matter where that pointer points or even if it points to a valid memory address.
The purpose of sizeof
is to measure how much memory static a certain structure occupies, and it is determined at compilation time, not execution. For dynamic memory allocation, the size of the allocated data depends on information that is only available at runtime, and therefore there is no way the compiler knows which one it would be. The solution is you calculate the size yourself if you need to, and at the end of the day, you don’t need it to just display the matrix on the screen.
I will comment here because I don’t think I have the authority to answer, but I believe the compiler will return the size of the type in which the pointer is set and not the size to which it points. That is, how it is defined as
int
and in its architecture this type consumes 4 bytes of memory, so thesizeof
of the same will be 4. Has a discussion about it at Soen.– Woss
Did the answer solve your question? Do you think you can accept it? See [tour] if you don’t know how you do it. This would help a lot to indicate that the solution was useful to you. You can also vote on any question or answer you find useful on the entire site.
– Maniero