【问题标题】:C release dynamically allocated memoryC释放动态分配的内存
【发布时间】:2013-11-22 14:44:23
【问题描述】:

我已经定义了返回多维数组的函数。

行分配

arr = (char **)malloc(size);

列分配(循环中)

arr[i] = (char *)malloc(v);

返回类型是char**

一切正常,除了释放内存。如果我在函数返回的数组上调用 free(arr[i]) 和/或 free(arr),它就会崩溃。

编辑:

分配函数

pole = malloc(zaznamov);  
char ulica[52], t[52], datum[10];  
float dan;  
int i = 0, v;
*max = 0;
while (!is_eof(f))
{
    get_record(t, ulica, &dan, datum, f);
    v = strlen(ulica);
pole[i] = malloc(v);
strcpy(pole[i], ulica);
pole[i][v-1] = '\0';
if (v - 1 > *max)
{
    *max = v;
}
i++;
}
return pole;

我调用函数的主要部分

pole = function();

释放内存

int i;
for (i = 0; i < zaznamov; i++)  
{  
    free(pole[i]);  
    pole[i] = NULL;  
}  
free(pole);  
pole = NULL;

【问题讨论】:

  • 不要转换 malloc 的结果。
  • 你能展示一个失败的完整例子吗?一般来说,每次调用malloc 之后都应该紧跟一次调用free,这样你描述的代码就可以工作了。该错误可能存在于您尚未告诉我们的代码中。
  • 很可能它崩溃了,因为你在代码中的某个地方写了越界,破坏了 malloc 存储的元数据。
  • 请在上面编辑您的问题,而不是在评论中写这么多代码。

标签: c memory-management malloc free


【解决方案1】:

几件事,你不应该转换 malloc 的结果。

char** alloc_2d_char(int rows, int cols) {
  char *data = malloc(rows*cols*sizeof(char));
  char **array= malloc(rows*sizeof(char*));
  for (int i=0; i<rows; i++)
   array[i] = &(data[cols*i]);
 return array;
}

当然,你需要检查 NULL 是否从 malloc 中返回

免费:

void free_2d_pixel(char **data){
  free(data[0]);
  free(data);
}

【讨论】:

    【解决方案2】:

    由于您没有显示完整的分配代码,因此很难知道您做错了什么。鉴于我们所看到的,你应该有类似的东西:

    size_t n = 27;
    size_t size = n * sizeof(char *);
    char **arr = (char **)malloc(size);
    size_t v = 39;
    
    if (arr == 0)
        ...report error and bail out...
    
    for (size_t i = 0; i < n; i++)
    {
        if ((arr[i] = (char *)malloc(v)) == 0)
        {
            // Out of memory — release what was already acquired
            for (size_t j = 0; j < i; j++)
                 free(arr[i]);
            free(arr);
        }
    }
    

    然后释放数据:

    for (size_t i = 0; i < n; i++)
        free(arr[i]);
    free(arr);
    

    您必须以某种方式跟踪数组中的元素数量(我的代码中的n)。弄错是个问题。以另一种顺序进行释放也是如此。在元素之前释放arr 将是一个严重的错误。

    至于是否转换,malloc() 的返回值,就我而言,由你决定。 C++ 需要它。在标准 C 之前的日子里,C 曾经需要它。只要您始终使用诸如必须在调用它之前声明 malloc() 的选项进行编译,它就没有害处。 C99 要求在严格的一致性模式下。让你的编译器需要它。我几乎总是使用严格的编译器选项来确保发生这种情况:

    gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror ...
    

    如果您对此感到草率,请不要投 malloc()。如果你很小心,你可以在适合你的情况下投射。

    【讨论】:

      猜你喜欢
      • 2017-06-13
      • 2023-03-03
      • 1970-01-01
      • 2011-03-17
      • 2013-04-14
      • 1970-01-01
      • 2013-01-27
      相关资源
      最近更新 更多