从 C 函数中释放二维指针数组

Freeing 2D Array of Pointers from a Function in C

在 C 中,我有以下用于创建二维数组的函数。

int** createMatrix(int xdim, int ydim){
        int** mat = malloc(xdim*sizeof(int*));

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

        return mat;
}

在调用函数中(本例中为 int main()):

int **matA = createMatrix(10, 10);
free(matA);

我似乎在释放内存方面遇到问题,我想知道这是否是因为变量 "mat" 从未被释放。

像我一样释放(matA)够了吗?还是我无法释放(mat)的问题?

您需要先单独释放每一行(基本上是您创建的相反过程)

for(i=0; i < xdim; i++)
     free(matA[i]);

free(matA)

我建议创建一个 freeMat 函数来执行此操作

释放指针实际上意味着您正在释放它指向的内存以供另一次分配。所以是的,释放 matA 将释放您分配的内存块,但您需要释放 mat 的每个分配的元素。

for(int i = 0; i < xdim; i++)
    free(matA[i]);
free(matA);

只免费matA是不够的。 matA 引用指向 intxdim 指针的存储,但每个指针都引用其自己单独的存储块。如果您以这种方式分配一个数组数组,那么您不仅必须释放外部数组,而且(首先)释放每个内部数组。

当您取消分配之前为变量分配的内存时(例如,ptr),您将无法访问它。 free 函数不会更改 ptr 的值,因此它仍然指向相同的位置(现在无效)。

对于数组,您必须逐行遍历数组以释放您分配的每个元素,然后再释放指向该元素的变量的内存。这里的所有用户都这么告诉你。

如果您首先释放 [xdim] 中的一个,您将无法访问所有 [ydim]内存泄漏) 它指向的地方。换句话说,您将无法释放它们。你机器上的 OS 可以自动释放它(但不能保证)但是控制释放内存的过程是一个很好的做法:

[ X ]---[ydim]--[ydim]-[ydim] 
[ X ]---[ydim]--[ydim]-[ydim]
[ X ]---[ydim]--[ydim]-[ydim]

所以最好释放元素而不是 "in charge" 其他元素。在您的情况下,它是 [ydim]s。首先释放这些元素,你不会丢失其他元素,你的 [xdim]s。然后你可以通过 [xdims] 并释放它们:

// freed `[ydim]` of the first `[xdim]`
[xdim]---[ X ]--[ X ]-[ X ] 
[xdim]---[ X ]--[ X ]-[ X ]
[xdim]---[ X ]--[ X ]-[ X ]

// now you can free all `[xdim]`
[ X ]
[ X ]
[ X ]    

// the `matA` array has been freed