I need to create a matrix containing structs. My struct:
typedef struct {
int a;
int b;
int c;
} myStruct;
My method to create matrix
You access the 2D array by the incorrect pointer type.
The first element of myStruct matrix[5][5]
is an array myStruct[5]
.
Thus you must cast the result of calloc()
to a pointer to SO_WIDTH
-element-long array.
myStruct (*matrix)[SO_WIDTH] = calloc (SO_HEIGHT * SO_WIDTH, sizeof(myStruct));
Since C99 there is even no need for SO_WIDTH
, SO_HEIGHT
to be constants.
EDIT
It looks that the question got re-edited. The update answer is:
Use VLA from C99.
void myfunction(int rows, int cols, myStruct matrix[rows][cols]) {
...
}
Array calls are decayed to pointers.
When you pass them (arrays) to a function you need to specify all but the first dimension.
The compiler needs all the other dimensions for pointer arithmetic... Here is how you would declare and call in your example:
void f(myStruct p[][WIDTH]);
f(matrix);
When you do p++;
inside the function, the compiler knows that the next element is WIDTH * sizeof(myStruct)
bytes away in memory.
You could put any value for the in the first []
, it would simply be ignored.You have to know the value for the first dimension (probably passed by parameter or controlled as a global variable).
In C89, WIDTH
must be a constant and you can simply pass the matrix this way:
#include <stdlib.h>
#define WIDTH 5
typedef struct {
int a;
int b;
int c;
} myStruct;
void init_matrix(myStruct matrix[][WIDTH], int height) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < WIDTH; j++) {
matrix[i][j].a = matrix[i][j].b = matrix[i][j].c = 0;
}
}
}
int main() {
int height = 5;
myStruct (*matrix)[WIDTH] = malloc(height * sizeof *matrix);
if (matrix) {
init_matrix(matrix, height);
...
free(matrix);
}
return 0;
}
In C99, if variable length arrays (VLAs) are supported, both WIDTH
and HEIGHT
can be variable but the order of arguments must be changed:
#include <stdlib.h>
typedef struct {
int a;
int b;
int c;
} myStruct;
void init_matrix(int width, int height, myStruct matrix[][width]) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
matrix[i][j].a = matrix[i][j].b = matrix[i][j].c = 0;
}
}
}
int main() {
int height = 5;
int width = 5;
myStruct (*matrix)[width] = malloc(height * sizeof *matrix);
if (matrix) {
init_matrix(width, height, matrix);
...
free(matrix);
}
return 0;
}