[英]How do you free a 2D malloc'd array in C?
我正在用 C 创建一个二维数组; 我是否正确释放它?
// 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);
您必须为每个malloc
调用一次free
。 你的代码有一个malloc
和一个free
(地址相同),所以它是正确的。
对于每个malloc()
,必须有一个匹配的free()
。 因此,如果您在循环中调用malloc()
,那么稍后必须有一个类似的循环,该循环调用free()
次数也一样多。 你的代码有一个malloc()
和一个对应free()
所以是的,你有free
,你需要的一切d。
我见过的分配二维数组的最常见方法是执行以下操作:
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.
*/
然后稍后释放:
for (i = 0; i < num_rows; ++i)
free(arr[i]);
free(arr);
这使得外部尺寸保持num_row
指向指针的指针为INT(每个的num_row
指针指向“列”的起始地址)。 所以外部维度中的每个元素都指向一行,而在每一行中,内部维度('列')中有num_cols
元素,这只是一组num_cols
整数。 这对你有意义吗? 因此,您必须分配num_rows
整数指针,并且这些指针中的每一个都指向该行的第一“列”——对于每一行,您必须为num_cols
整数分配空间,因此您可以看到循环将总共num_rows * num cols
整数,它们的分配方式允许您使用数组索引符号(在这种情况下是二维的 - 外部维度中的每个元素都指向“行”的开头,其中包含指向开头的指针'列',因此是双指针)来访问元素。 我知道这可能会令人困惑,这就是为什么我试图用不同的时间/方式来描述它,但请提出任何问题,尤其是关于您特别不理解的问题,我将非常乐意与您合作你帮助理解它。
我并不是说您必须以这种方式创建二维数组; 你的方式也很好,我只是想告诉你这种方式,因为你很可能会遇到它,因为它很常见。
另外,看看 Valgrind。 您可以使用该工具查看您是否忘记了任何free()
s / 有一个不匹配的malloc()
,并让您知道是否有任何分配的内存无法访问/泄漏(可能在调用free()
之前更改了指针free()
所以调用没有正确释放内存,你会得到一个泄漏)。
RastaJedi - 另一件需要注意的事情:在调用 free() 之后,最好将 free'd 变量设置为 NULL,这有助于防止在释放后使用。 此外,如果您在一个代码块中 malloc,然后在某个被调用的函数中释放,然后从该函数返回,有时 C 会忘记最终的释放(在您的示例中, free(arr) ),您应该将变量设置为返回时为 NULL。
我来到这里,并验证了我在我正在处理的代码中编写的 malloc 和 free 调用确实与您的“常见”方式完全一样,但一直遇到 Seg Fault,因为我在 main 中使用了 malloc,从接收数组的双间接头的辅助函数中释放。 将所有这些都包装在一个用于用户交互的 while 循环中,第二遍是检查数组头是否为 NULL,但没有将其视为 NULL,尽管在辅助函数内显式设置为 NULL。 使用调试器遍历代码是我识别行为的方式,以及我来查找的原因。
释放后,内存可用,并以各种方式(和随机)重新分配; 当具有 free() 调用的函数返回时,分配的内存已被释放,但似乎调用代码仍持有指向内存中该位置的指针。 然后存在可能的竞争条件; 当调用代码重新获得控制权时,无法保证用于数组头的变量指向的位置,因此在函数返回后将变量设置为 NULL 是一个很好的主意。
虽然您可以使用 malloc 的指针进行传递引用行为,但在某个函数内部调用 free() 之后,传递引用行为会中断(因为被引用的东西已经被释放了)。
所以,感谢您的回答,这证实了我在看问题的错误部分 - 只是想也许其他人可能会在这里绊倒,并且可能遇到与我相同的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.