在具有多个 malloc() 的二维数组的指针上使用 free()?

Using free() on pointers of two dimensional array with multiple malloc()?

我有一个函数,它在返回数组指针的函数中分配一个二维数组。创建数组需要一个指针数组,每个指针包含二维数组一行的地址。

完成此数组后,如何正确释放此函数之外的这两个 malloc() 调用?

int** allocateMatrix(int rows, int cols)
{
    int* arr = malloc(rows*cols*sizeof(int));
    int** matrix = malloc(rows*sizeof(int*));
    int i;
    for(i=0; i<rows; i++)
    {
        matrix[i] = &(arr[i*cols]);
    }
    return matrix;
 }

函数是这样使用的:

int** 2d_arr = allocateMatrix(row,cols);

谢谢!

您只能将从 malloc 收到的内容传递给 free。所以调用free的次数必须和调用malloc.

的次数一样

2d_arr的第一行,即2d_arr[0],包含&arr[0*cols] == &arr[0] == arr。所以你想释放它和 matrix 本身:

free(2d_arr[0]);
free(2d_arr);

这会起作用:

void freeMatrix( int **matrix )
{
    free( matrix[ 0 ] );
    free( matrix );
}

因为,对于i == 0,这段代码

matrix[i] = &(arr[i*cols]);

matrix[ 0 ] 设置为 arr[0] 的地址,这与第一个 malloc 调用返回的值相同:

int* arr = malloc(rows*cols*sizeof(int));

矩阵分配这样写就更清楚了

int** allocateMatrix(int rows, int cols)
{
    int** matrix = malloc(rows*sizeof(int*));
    matrix[ 0 ] = malloc(rows*cols*sizeof(int));

    int i;
    for(i=1; i<rows; i++)
    {
            matrix[i] = &(arr[i*cols]);
    }
    return matrix;
 }

注意 malloc() 顺序的变化,直接分配给 matrix[ 0 ],以及循环索引从 1 开始的变化。

我建议你使用单个malloc()分配整个内存区域,这样更容易作为单个指针进行管理。

我相信您的函数的以下修改版本应该有效。

int** allocateMatrix(int rows, int cols)
{
    size_t  sMemSize = rows*sizeof(int*) + rows*cols*sizeof(int);
    int** matrix = malloc(sMemSize);
    int* arr = (int *) (matrix + rows);
    int i;
    for(i=0; i<rows; i++)
    {
        matrix[i] = &(arr[i*cols]);
    }
    return matrix;
 }

然后你可以做 free(2d_arr); where int** 2d_arr = allocateMatrix (nRows, nCols);.