【问题标题】:how to properly free a char **table in C如何在 C 中正确释放 char **表
【发布时间】:2010-03-20 16:50:44
【问题描述】:

我需要您对这段代码的建议: 表字段选项 [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;

}

【问题讨论】:

    标签: c malloc


    【解决方案1】:

    问题是这样的:

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

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

    关键是始终以与malloc'ed 相同的方式保持free 内存。所以,如果你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)不是一个常数,您需要自己跟踪它,否则您无法知道释放时要循环多少次。

    【讨论】:

    • 如果大小 (256) 不是一个常数,你不能终止数组而不是跟踪它的长度吗?
    【解决方案2】:

    frees 的数量应该与 mallocs 的数量相同。

    在您的代码中,您分配了指针数组,但没有为要指向的数组的各个元素分配任何内存。但是你的释放代码就像你写的一样。

    【讨论】:

      【解决方案3】:

      我将在这里添加亚当的答案,因为这可能不适合评论。亚当是完全正确的。但是,我怀疑您的 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;
      }
      

      然后你像这样从 main 调用:

      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);
      

      希望能给你更多的想法,Adam,请随时根据需要将任何/所有这些内容编辑到你的答案中,无论如何它都来自你的答案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-15
        • 1970-01-01
        • 1970-01-01
        • 2020-03-21
        • 2018-03-14
        • 2011-11-11
        • 2015-05-10
        • 1970-01-01
        相关资源
        最近更新 更多