如何在C中正确释放char **表

时间:2010-03-20 16:50:44

标签: c malloc

我需要你对这段代码的建议: 表字段选项[0],选项[1]等...似乎没有正确释放。 谢谢你的回答

int main()
{
  ....
  char **options;
  options = generate_fields(user_input);
  for(i = 0; i < sizeof(options) / sizeof(options[0]); i++)  {
    free(options[i]);
    options[i] = NULL;
  }

  free(options);
}

char ** generate_fields(char *) 
{
   char ** options = malloc(256*sizeof(char *));
   ...
   return options;

}

3 个答案:

答案 0 :(得分:16)

问题在于:

for(i = 0; i < sizeof(options) / sizeof(options[0]); i++)

options是指针类型,而不是数组类型,因此sizeof(options)将始终相同(通常是32位机器上的4个字节或64位机器上的8个字节),所以sizeof(options)/sizeof(options[0])几乎总是1。

关键是永远free内存与您malloc编辑内存的方式相同。因此,如果您malloc是一个二维数组,然后是malloc一系列一维数组,则需要在释放时反向执行:

char ** generate_fields(char *) 
{
   char ** options = malloc(256*sizeof(char *));
   for(int i = 0; i < 256; i++)
       options[i] = malloc(some_size);
   return options;
}

void free_fields(char ** options)
{
    for(int i = 0; i < 256; i++)
        free(options[i]);
    free(options);
}

请注意,如果大小(在这种情况下为256)不是常量,则需要自己跟踪它,否则你无法知道在释放时循环多少次。

答案 1 :(得分:7)

您应该拥有与free相同数量的malloc

在代码中分配指针数组,但不为数组的各个元素指定任何内存。但是你的解放代码就像你写的一样。

答案 2 :(得分:3)

我将在这里添加Adam的答案,因为这可能不适合评论。亚当完全正确。我怀疑你的generate_fields函数,但是,实际上可能从用户那里得到了输入,我不确定。无论如何,有两种方法可以解决这个问题:

char ** generate_fields(char *, int num_fields, int size_of_field) 
{
   char ** options = malloc(num_fields*sizeof(char *));
   for(int i = 0; i < num_fields; i++)
       options[i] = malloc(size_of_field);
   return options;
}

以及相应的免费功能,为简洁起见,我将省略。你可以看到发生了什么 - 我们传递的是字段数和字段大小。根据需要改变它。另一种选择是将生成字段传递回从数组大小调用的例程。我会做这样的事情:

int generate_fields(char** options) 
{
   int num_fields = 0;
   // somewhere here we get num_fields
   options = malloc(num_fields*sizeof(char *));
   for(int i = 0; i < num_fields; i++)
       options[i] = malloc(size_of_field);
   return num_fields;
}

你这样打电话给主要人员:

int main()
{
    int sizeofarray = 0;
    char** fields;
    sizeofarray = generate_fields(fields);

或者,如果您不喜欢这种符号,您可以随时坚持自己拥有的内容:

char** generate_fields(int* size) 

作为函数原型(这次返回选项并在代码中的某处执行size=并从main调用,如下所示:

int sizeofarray = 0;
char** options;
options = generate_fields(&sizeofarray);

希望能给你一些更多的想法,亚当,你可以随意将你的任何/所有这些想法编辑到你的答案中,无论如何它来自你的答案。