Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct use of free() when deallocating a 2d matrix in c

I'm just starting to learn coding in c, and I have a few questions regarding 2d matrices in combination with the free() command.

I know that you first need to create an array with pointer, pointing to the different columns of the matrix:

double **array = (double **)malloc(5*sizeof(double *));
for(int n = 0; n<5; n++){

array[n] = (double *) malloc(6*sizeof(double));

I know that the correct way to then deallocate this matrix is to first deallocate the individual rows and then the array pointer itself. Something along the lines of:

for (i = 0; i < nX; i++){  
   free(array[i]); }     

free(array);

My question is: Why is this necessary? I know that this incorrect, but why can't you just use: free(array)? This would deallocate the pointer array, to my understanding. Won't the memory that is used by the columns just be overwritten when something else needs acces to it? Would free(array) lead to corrupted memory in any way?

Any help is much appreciated!

like image 269
B.Ing Avatar asked Dec 08 '22 13:12

B.Ing


2 Answers

Your code, not only allocate memory for array of pointers (the blue array), but in the for loop, you also allocate memory for the red arrays as well. So, free(array) line, alone, will just free the memory allocated by the blue array, but not the red ones. You need to free the red ones, just before loosing the contact with them; that is, before freeing the blue array.

And btw;

Won't the memory that is used by the columns just be overwritten when something else needs acces to it?

No. The operating system will keep track of the memory allocated by your process (program) and will not allow any other process to access the allocated memory until your process terminates. Under normal circumstances —I mean, remembering the C language not having a garbage collector— the OS never knows that you've lost connection with the allocated memory space and will never attempt like, "well, this memory space is not useful for this process anymore; so, let's de-allocate it and serve it for another process."

enter image description here

like image 170
ssd Avatar answered Dec 11 '22 09:12

ssd


It would not lead to corruption, no, but would create a memory leak.

If done once in your program, it probably doesn't matter much (a lot of professional/expensive applications have - small,unintentional - memory leaks), but repeat this in a loop, and you may run out of memory after a while. Same thing if your code is called from an external program (if your code is in a library).

Aside: Not freeing buffers can be a useful way (temporarily) to check if the crashes you're getting in your programs originate from corrupt memory allocation or deallocation (when you cannot use Valgrind). But in the end you want to free everything, once.

If you want to perform only one malloc, you could also allocate one big chunk, then compute the addresses of the rows. In the end, just deallocate the big chunk (example here: How do we allocate a 2-D array using One malloc statement)

like image 38
Jean-François Fabre Avatar answered Dec 11 '22 09:12

Jean-François Fabre