(corrected the code after a few good comments pointing out some mistakes in the previous version of the code)
If I'm right, the best way to dynamically allocate a 2D array of structs in C is the following:
struct xx(*array2d)[y] = malloc(sizeof(struct xx[x][y]));
Does it make any difference whether I store the structs in the array or store pointers to them?
I was also wondering if I may simply deallocate the allocated memory in the following way:
void free2d(int x, int y, struct xx array2d[x][y]) {
free(array2d);
}
CodePudding user response:
Identifiers in C cannot begin with numbers so 2darray
won't work.
Formally, the most correct way to allocated a 2D array dynamically is:
struct xx (*array)[x][y] = malloc(sizeof(struct xx[x][y]));
However that makes accessing the array cumbersome, because we would have to de-reference the array pointer first:
(*array)[i][j]
A common trick to avoid this is to have the array pointer not point at the "whole" 2D array, but to the first item. Which would be a struct xx [y]
array in this case.
So we can use a pointer to the first element but still allocate the correct amount:
struct xx (*array)[y] = malloc(sizeof(struct xx[x][y]));
And now we can use this as
array[i][j]
In either of the two examples above, you free it with a single free(array)
call.
CodePudding user response:
The allocation code is a bit incorrect.
- variable name cannot start with a digit, thus identifier
2darray
is illegal. Usearray2d
instead - memory allocation code look almost correct. Note that
array2d
would be a pointer to array ofx
elements of typestruct xx
. Thus the correct allocation code swap order ofx
andy
in sizeof expression.
struct xx (*array2d)[x] = malloc(sizeof(struct xx[y][x]));
If you want x
be the first dimensions use:
struct xx (*array2d)[y] = malloc(sizeof(struct xx[x][y]));
Personally I prefer to use the following pattern because it is less error prone:
struct xx (*array2d)[x] = calloc(y, sizeof *array2d);
- Passing to function. It is simple, just pass array dimensions as arguments and then the array itself.
void foo(int x, int y, struct xx array2d[static x][y]) {
Note that parameter array2d
is actually a pointer to array. The "static extent" tells the compiler that at least x
elements pointer by the pointer are valid. It is very useful for documentation. Moreover static
makes the declaration visually distinct from a declaration of an array.
- Deallocation. The
free2d
function could be used if it followed the pattern from point 2. However I recommend simply usingfree(array2d);
CodePudding user response:
I would use objects instead of types.
struct xx(*array2d)[cols] = malloc(rows *sizeof(*array2D));
To deallocate you do not need sizes only void
pointer to your array
void free2d(void *array2d) {
free(array2d);
}
or simple use free
with your pointer to the array.