如何正确释放char ***内存在C中我没有内存泄漏

时间:2014-07-30 09:10:19

标签: c memory-management memory-leaks

我收到了以下代码

int rows = 123;
int cols = 12;
char ***data = (char ***)malloc(rows * sizeof(char **));
if(data) {
    for(int i = 0; i < num_rows; i++)
    {
        data[i] = (char **)malloc(cols * sizeof(char *));
        if(!data[i])
        {
            for(int j = 0; j < i; j++)
                free(data[j]);
            free(data);
            printf("no memory\n");
            return -1;
        }
    }
}
char randomData[] = "<Inserts random string here everytime>";
for(int row = 0; row < rows; row++) {
     for(int col = 0; col < cols; col++) {
         data[row][col] = (char *) malloc(sizeof(char) * (1 + strlen(randomData)));
         strcpy(data[row][col], randomData);
     }
}

我为此stackoverflow编写的这个示例是因为实际代码类似,但是从每个SQL行和每列输出<Inserts random string here everytime>

我只想制作像data[row][column]

这样的多维数组

我完成后如何正确释放它?

我想要清除它我必须首先清除第一颗星。 char *

for(int row = 0; row < rows; row++) {
     for(int col = 0; col < cols; col++) {
         free(data[row][col]);
     }
}

然后清理第二颗星char **

for(int row = 0; row < rows; row++) {
     free(data[row]);
}

然后我终于可以清除最后一个三星char ***

    free(data);

这是你怎么做的?

,似乎有点太过分了
for(int row = 0; row < rows; row++) {
     for(int col = 0; col < cols; col++) {
         free(data[row][col]);
     }
}

足够?

3 个答案:

答案 0 :(得分:3)

您必须取消分配malloc&#39; ed。

的所有内容

最多可以通过写:

来保存循环
for(int row = 0; row < rows; row++) {
     for(int col = 0; col < cols; col++) {
         free(data[row][col]);
     }
     free(data[row]);
}
free(data);

如果你想在一次传递中取消分配,你必须在一次传递中分配,但是对于一个指针数组来说它很棘手,并且必须用红色闪烁字体进行注释:

data = malloc(rows * (1 + cols) * sizeof(void *));
for (i=0; i<rows; i++) {
    data[i] = &(data[cols * i]);
}

取消分配将是:

for(int row = 0; row < rows; row++) {
     for(int col = 0; col < cols; col++) {
         free(data[row][col]);
     }
}
free(data);

如果您愿意,可以直接分配2D数组:

data = malloc(rows * cols * sizeof(void *));

但是,您必须通过data[j + i * rows] ...访问各个元素...以红色闪烁字体进行评论...

答案 1 :(得分:2)

你需要像malloc一样免费

要释放整个数组,它取决于您的数组维度

让我们先看看你如何分配这个数组:

1 - char ***array = char pointer to 2d arrays (A)

2 - **array= char pointer to 2d array         (B)

3 - *array= char pointer to (vector) of char  (C)

如果您有***阵列,则需要从:

开始
1 - freeing each vector of your inner array (C)
2 - freeing inner array pointer             (B)                  
3 - freeing the main pointer                (A)

您可以这样做:

for(int row = 0; row < rows; row++) {
    for(int col = 0; col < cols; col++) {
        free(data[row][column]);
    }
    free(data[row]);
}
free(data);

答案 2 :(得分:2)

每次拨打malloc都需要拨打一次free。您已经概述了正确的(!)方法来释放所有分配。 free的数量不应该是一个问题(毕竟,对malloc的完全相同的调用数没有问题。)

如果要进行测试以确定,请添加一些低级调试代码:

  1. 在例程的顶部添加一个整数int number_of_allocations = 0;
  2. 在每个malloc后增加
  3. 在每个free后减少
  4. 测试最终的净结果是否为0。
  5. 据我所知,那里应该没有泄漏。