简体   繁体   中英

C function for deallocating memory of 2D, 3D... arrays

I have a question, in my set-up I have variables like this:

bool** array_2d_bool;
char** array_2d_char;

...

So, for deallocating memory, I have the following:

void free_bool(bool** mat, int m)
{
    int i;
    for (i = 0; i < m; i++)
    {
        free(mat[i]);
    }
    free(mat);
}

However, I have to write a function for every type of 2D or 3D array I want to deallocate. Is there a way to write a function like this one?:

void deallocate_2d(void**, int m)

So that I can just use one function for deallocating any 2D array...

bool** array_2d_bool;
char** array_2d_char;

These are not 2D arrays and cannot be used at pointing at 2D arrays. At best they can be used to point at the first element of an array of pointers.

And the only reason why you would want to use an array of pointers is when you want a lookup table, where each pointed-at type has different length, such as a string lookup table or a chained hash table. This isn't the case here, you just want a 2D array.

Using pointer-to-pointer for allocating a 2D array dynamically is always wrong , for multiple reasons: it doesn't create an actual array (so you can't use memcpy() and similar on it), it involves complex allocation/freeing that potentially leads to leaks, it causes heap segmentation and slower allocation, it gives poor cache performance and so on.

Instead allocate a 2D array:

malloc( sizeof(bool[x][y] );

Then point at it with an array pointer.

bool (*array_2d_bool)[x][y] = malloc( sizeof(bool[x][y] );

For ease of use, it is however much more convenient to point at the first array in this array of arrays, rather than pointing at the whole 2D array. So change it to this:

bool (*array_2d_bool)[y] = malloc( sizeof(bool[x][y] );

Now you can use it as array_2d_bool[i][j] .

And when you are done, free it:

free(array_2d_bool);

You don't have nD-arrays. Pointers are no arrays. They also have different semantics.

Using a true nD-array makes deallocation straight forward:

#define INNER 10
#define OUTER 20

int (*arr)[INNER] = malloc(sizeof(*arr) * OUTER);

...

free(arr);

Except for the declaration, this is straight forward for more dimensions. free ing is even the same. No need for a seperate deallocation function.

In computational science, it is pretty much standard for you to malloc() a 1D “array” (ie for an m by n matrix of double s, do a single double *a=malloc(m*n*sizeof(double)) ), then do the index computation yourself, ie to get the element at i , j stored in a , you use a[i*n+j] . This has several advantages, including that it obviates the need to do multiple/nested malloc() s and free() s, adds very little in the way of cognitive overhead for the programmer, particularly since you can abstract the index computation away in a little inline function or a macro, and is readily extensible to higher dimensions.

A more detailed explanation can be found in this answer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM