C: Correctly freeing memory of a multi-dimensional array C: Correctly freeing memory of a multi-dimensional array c c

C: Correctly freeing memory of a multi-dimensional array


OK, there's a fair deal of confusion explaining exactly what order thenecessary free() calls have to be in, so I'll try to clarify whatpeople are trying to get at and why.

Starting with the basics, to free up memory which has been allocatedusing malloc(), you simply call free() with exactly the pointerwhich you were given by malloc(). So for this code:

int **a = malloc(m * sizeof(int *));

you need a matching:

free(a);

and for this line:

a[i]=malloc(n * sizeof(int));

you need a matching:

free(a[i]);

inside a similar loop.

Where this gets complicated is the order in which this needs to happen. Ifyou call malloc() several times to get several different chunks ofmemory, in general it doesn't matter what order you call free() whenyou have done with them. However, the order is important here for a veryspecific reason: you are using one chunk of malloced memory to holdthe pointers to other chunks of malloced memory. Because you mustnot attempt to read or write memory once you have handed it back withfree(), this means that you are going to have to free the chunks withtheir pointers stored in a[i] before you free the a chunk itself.The individual chunks with pointers stored in a[i] are not dependent on eachother, and so can be freed in whichever order you like.

So, putting this all together, we get this:

for (i = 0; i < m; i++) {   free(a[i]);}free(a);

One last tip: when calling malloc(), consider changing these:

int **a = malloc(m * sizeof(int *));a[i]=malloc(n * sizeof(int));

to:

int **a = malloc(m * sizeof(*a));a[i]=malloc(n * sizeof(*(a[i])));

What's this doing? The compiler knows that a is an int **, so it candetermine that sizeof(*a) is the same as sizeof(int *). However, iflater on you change your mind and want chars or shorts or longs orwhatever in your array instead of ints, or you adapt this code for lateruse in something else, you will have to change just the one remainingreference to int in the first quoted line above, and everything elsewill automatically fall into place for you. This removes the likelihoodof unnoticed errors in the future.

Good luck!


Undo exactly what you allocated:

  for (i = 0; i < m; i++) {       free(a[i]);  }  free(a);

Note that you must do this in the reverse order from which you originally allocated the memory. If you did free(a) first, then a[i] would be accessing memory after it had been freed, which is undefined behaviour.


You need to iterate again the array and do as many frees as mallocs for the pointed memory, and then free the array of pointers.

for (i = 0; i < m; i++) {       free (a[i]);}free (a);