繁体   English   中英

你如何在 C 中释放一个 2D malloc 数组?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM