Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you free a 2D malloc'd array in C?

Tags:

c

free

I'm creating a 2D Array in C; am I freeing it correctly?

// create
int n = 3;
int (*X)[n] = malloc(sizeof(int[n][n]));

// set to 0
for(int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        X[i][j] = 0;
    }
}   

// is this all I need?
free(X);
like image 696
Austin Avatar asked Oct 11 '25 14:10

Austin


2 Answers

You must call free once for each malloc. Your code has one malloc and one free (with the same address) so it is correct.

like image 60
M.M Avatar answered Oct 14 '25 06:10

M.M


For every malloc(), there must be a matching free(). So if you call malloc() in a loop, there must be a similar loop later on that calls free() just as many times. Your code has one malloc() and one corresponding free(), so yes, you have freed everything you need to.

The most common way I've seen to allocate a two-dimensional array is to do something like:

int **arr = malloc(sizeof (int *) * num_rows);

for (i = 0; i < num_rows; ++i)
        arr[i] = malloc(sizeof (int) * num_cols);
/*
  * Using `sizeof *arr` and `sizeof **arr`
  * respectively would have been more safe,
  * but for the purpose of this example, I think
  * using `int *` and `int` is simpler to
  * understand.
  */

then later to free:

for (i = 0; i < num_rows; ++i)
        free(arr[i]);

free(arr);

This makes the outer dimension hold num_row pointers to pointers to int (each of the num_row pointers points to the starting address of the 'column'). So each element in the outer dimension points to a row, and in each row there are num_cols elements in the inner dimension (the 'columns'), which is just a group of num_cols integers. Does this make sense to you? So you have to allocate num_rows integer pointers, and each one of these points to the first 'column' of that row--for each row you have to allocate space for num_cols integers, so you can see the loop will make a total of num_rows * num cols integers, and they way they are allocated allows you to use array indexing notation (two-dimensional in this case--each element in the outer dimension points to the start of a 'row', which contains a pointer to the start of a 'column', hence the double pointer) to access the elements. I know this is probably confusing, that is why I tried to describe it so many different times/ways, but please just ask any questions, especially about what you don't understand in particular, and I will be more than happy to work with you in helping understand it.

I'm not saying you have to create your 2-D array this way; your way works fine too, I just wanted to show you this way since you are likely to run into it since it's very common.

Also, look into Valgrind. You can use that tool to see if you have forgotten any free()s / have an unmatched malloc(), and lets you know if there is any allocated memory unreachable/leaked (maybe the pointer was changed before the call to free() so the call doesn't properly free the memory and you get a leak).

like image 28
RastaJedi Avatar answered Oct 14 '25 06:10

RastaJedi