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

十年热恋 提交于 2021-01-27 09:10:58

问题


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!


回答1:


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."




回答2:


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)




回答3:


This is needed because C does not have a garbage collector. Once you allocate memory with malloc or similar function, it is marked as "in use" for as long as your program is running.

It does not matter if you no longer hold a pointer to this memory in your program. There is no mechanism in the C language to check this and automatically free the memory.

Also, when you allocate memory with malloc the function does not know what you are using the memory for. For the allocator it is all just bytes.

So when you free a pointer (or array of pointers), there is no logic to "realize" these are pointers that contain memory addresses.

This is simply how the C language is designed: the dynamic memory management is almost1 completely manual - left to the programmer, so you must call free for every call to malloc.


1 C language does handle some of the more tedious tasks needed to dynamically allocate memory in a program such as finding where to get a free continuous chunk of memory of the size you asked for.




回答4:


Let's take this simple example:

int **ptr = malloc(2*sizeof *ptr);
int *foo = malloc(sizeof *foo);
int *bar = malloc(sizeof *bar);
ptr[0] = foo;
ptr[1] = bar;
free(ptr);

If your suggestion were implemented, foo and bar would now be dangling pointers. How would you solve the scenario if you just want to free ptr?



来源:https://stackoverflow.com/questions/53659654/correct-use-of-free-when-deallocating-a-2d-matrix-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!