我刚刚开始学习c语言中的编码,并且我对与free()命令结合使用的二维矩阵有一些疑问。
我知道您首先需要使用指针创建一个数组,该数组指向矩阵的不同列:
double **array = (double **)malloc(5*sizeof(double *));
for(int n = 0; n<5; n++){
array[n] = (double *) malloc(6*sizeof(double));
我知道,然后重新分配此矩阵的正确方法是首先重新分配各个行,然后再分配数组指针本身。类似于:
for (i = 0; i < nX; i++){
free(array[i]); }
free(array);
我的问题是:为什么这是必要的?我知道这不正确,但是为什么不能只使用:free(array)?据我了解,这将释放指针数组。当需要其他权限时,是否仅会覆盖列所使用的内存? free(array)会以任何方式导致内存损坏吗?
非常感谢您的帮助!
答案 0 :(得分:6)
这不会导致损坏,不会,但是会造成内存泄漏。
如果在程序中执行一次,则可能没什么关系(很多专业/昂贵的应用程序都有-小,无意的-内存泄漏),但请循环执行此操作,之后您可能会耗尽内存一会儿。如果从外部程序(如果您的代码在库中)调用代码,也是如此。
此外:不释放缓冲区可能是一种有用的方法(临时),它可以检查您程序中崩溃的原因是否是由于内存分配或释放损坏(当您无法使用Valgrind时)。但是最后您想要释放所有内容,一次。
如果只想执行一个malloc
,则还可以分配一个大块,然后计算行的地址。最后,只需重新分配较大的块(此处为示例:How do we allocate a 2-D array using One malloc statement)
答案 1 :(得分:6)
您的代码不仅为指针数组(蓝色数组)分配内存,而且在for循环中,您还为红色数组分配内存。因此,仅free(array)
行会释放蓝色数组分配的内存,而不释放红色数组分配的内存。您需要先释放红色的手指,然后再失去与它们的联系。也就是说,在释放蓝色阵列之前。
还有顺便说一句
在其他需要访问权限的情况下,列使用的内存不会只是被覆盖吗?
不。操作系统将跟踪您的进程(程序)分配的内存,并且在您的进程终止之前,不允许任何其他进程访问分配的内存。在正常情况下(我的意思是,记住C语言没有垃圾收集器),操作系统永远不会知道您与分配的内存空间已经失去连接,并且永远不会尝试,例如,“好吧,此内存空间对于此过程没有用不再;因此,让我们取消分配它并将其用于另一个进程。”
答案 2 :(得分:2)
这是必需的,因为C没有垃圾收集器。
使用malloc
或类似功能分配内存后,只要程序正在运行,它就会被标记为“正在使用”。
如果您不再在程序中保留指向该存储器的指针,则没有关系。 C语言没有机制可以检查并自动释放内存。
此外,当您使用malloc
分配内存时,该函数不知道您使用的内存是什么。对于分配器,它们全都是字节。
因此,当您free
指针(或指针数组)时,没有逻辑可“实现”包含内存地址的指针。
这就是C语言的设计方式:动态内存管理几乎完全是 1 完全手动-留给程序员,所以每次调用{{ 1}}。
1 C语言确实处理了在程序中动态分配内存所需的一些较繁琐的任务,例如找到从何处获取所需大小的免费连续内存块。>
答案 3 :(得分:0)
让我们举一个简单的例子:
Unit: milliseconds
expr min lq mean median uq
question 4.312094 4.448391 4.695276 4.570860 4.755748
answer 2.932146 3.017874 3.191262 3.117627 3.240688
string_add 3.388442 3.466466 3.699363 3.534416 3.682762
max neval cld
10.29253 100 c
8.24967 100 a
9.05441 100 b
如果您的建议已实现,那么int **ptr = malloc(2*sizeof *ptr);
int *foo = malloc(sizeof *foo);
int *bar = malloc(sizeof *bar);
ptr[0] = foo;
ptr[1] = bar;
free(ptr);
和foo
现在将成为悬空指针。如果您只想释放bar
,您将如何解决方案?