释放双重指针

20

我使用双指针创建了一个二维矩阵,代码如下:

int** pt; pt = (int*) malloc(sizeof(int)*10);

我知道指针是这样被释放的

free(ptr);

如何释放双重指针?

如果我们打印了一些东西,然后释放了该内存并退出程序呢?最终的内存是由我们使用的内存组成的,还是与最初相同?


3
这取决于你如何调用malloc。代码在哪里? - Eitan T
@bledi 所以你需要遍历这些指针,首先释放指向的数据。然后再释放指针本身。看看Attila的答案。 - Eitan T
请放上相关的malloc代码,同意。 - octopusgrabbus
在 C 语言中,不要对 malloc()realloc()calloc() 的调用结果进行强制类型转换 - 这是不必要的,且可能会掩盖一个严重错误,即缺少原型。 - mlp
3个回答

41

假设你有一个矩阵 mat

int** mat = malloc(10 * sizeof(int*));
for (int i=0; i<10; ++i) {
  mat[i] = malloc(10 * sizeof(int));
}

那么你可以释放矩阵的每一行(假设你之前已经正确地初始化了每一行):

for (int i=0; i<10; ++i) {
  free(mat[i]);
}

然后释放顶层指针:

free(mat);

针对你第二个问题:如果你分配内存并使用它,你将改变那段内存,即使你释放了它也不会“还原”(尽管你将无法可靠/可移植地访问它)。

注意:顶层的malloc正在使用sizeof(int*),因为你分配的是指向int的指针,而不是int本身--int*int的大小不能保证相同。


2

对于第一个问题,我会告诉你一个经验法则。

你调用free()的次数应该等于你调用malloc()calloc()的次数之和。

所以,如果你按照这样的方式分配了一个指向指针的指针,然后在每个指向整数的指针上使用了malloc(),那么你将释放“行”次,其中每个free()都是为每个指向整数的指针而释放的。

最后,在指向指针的指针上调用一次free()。这将平衡malloc() + calloc()free()的调用次数。


“你调用free()的次数应该等于你调用*alloc()的次数”,这就是总结。不过我想澄清一件事,根据https://en.cppreference.com/w/c/memory/free,我们需要向free传递一个单一指针,那么当我们传递一个双重指针时会发生什么?会进行隐式转换为单一指针吗? - KcFnMi

2
如果你的矩阵不是"不规则的",即所有行的长度都相同,那么你可以考虑以下方法:
  1. 手动访问它,即将其视为值的1D数组,并保留单独的width值。要访问(x,y)处的元素,请使用mat[y * width + x]
  2. 如果你真的想要mat[y][x]的方便性,可以通过调用一次malloc()来改进它,该函数分配指针数组和所有行,然后将指针初始化为指向每行。这种方法的优点在于可以使用单个free(mat);调用释放内存。
第二种方法可能如下所示:
double ** matrix_new(size_t width, size_t height)
{
  double **p = malloc(height * sizeof *p + width * height * sizeof **p);
  double *e1 = (double *) (p + height);
  size_t i;

  for(i = 0; i < height; ++i)
    p[i] = e1 + i * width;
  return p;
}

注意:以上内容未经测试,生产代码显然应该在使用p之前检查失败。

2
如果您只释放顶层指针,那么内部级别指向的缓冲区是否被引用?它们是否会被某个垃圾回收器默认释放?还是需要显式释放? - user2948075
1
除非我误解了这个问题,你正在为一个double *数组和一个大小为width * heightdouble二维数组分配空间。为什么不是malloc(height * sizeof(double *) + width * height * sizeof(double)?你的malloc中的+ width * height部分只会为矩阵中每个double分配一个字节的空间,这不足够。 - Michael Dorst
@MichaelDorst 因为这是一个错误,现在已经修复。非常感谢。 - unwind
但是你没有放置 free() 语句;@MichaelDorst,你是指这个吗?len = sizeof(int *) * rows + sizeof(int) * columns * rows;arr = (int **)malloc(len);。在这种情况下,我想知道如何释放这个双指针。 - vincent thorpe
@vincentthorpe 我不知道你在问什么。 - Michael Dorst

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接