Home > Enterprise >  dynamically allocate 2d array of structs in C
dynamically allocate 2d array of structs in C

Time:12-20

(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. Use array2d instead
  • memory allocation code look almost correct. Note that array2d would be a pointer to array of x elements of type struct xx. Thus the correct allocation code swap order of x and y 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);
  1. 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.

  1. Deallocation. The free2d function could be used if it followed the pattern from point 2. However I recommend simply using free(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.

  • Related