【问题标题】:Freeing multidimensional arrays in C在 C 中释放多维数组
【发布时间】:2012-01-26 03:00:27
【问题描述】:

假设我们有:

void createMultiArray(){
    int i,j;
    char*** codes = malloc(5 * sizeof(char**));
    for ( i = 0; i <= 4; i++ ) {
        codes[i] = malloc((i+1) * sizeof(char*));
        for ( j = 0; j <= i; j++ ) {
            codes[i][j] = malloc(2 * sizeof(char));
        }
   }

我应该如何释放codes

free(codes);

int i,j;
for(i = 0; i <=4; i++){
    for(j = 0; j <= i; j++){
        free(codes[i][j]);
    }
    free(codes[i]);
}
free(codes);

【问题讨论】:

  • 第二个不会导致内存泄漏 :) 这是可取的。
  • 它是“首选”,我们可以说“一个是对的,另一个不是”;)
  • 这不是你使用的多维数组

标签: c memory-management memory-leaks multidimensional-array free


【解决方案1】:

第二个是你想要的,free 不能也不会递归工作。每次当您执行malloc 时,请想想您要呼叫free 的地方。

附带说明,如果您接下来要做的是退出程序,请不要释放内存 - 这是没有意义的,并且可能需要相当长的时间。

【讨论】:

    【解决方案2】:

    第二个是正确的,而第一个是内存泄漏。根据经验,您希望为每个 malloc() 呼叫呼叫 free()

    【讨论】:

      【解决方案3】:

      这样想 - 每个malloc 都应该有一个free

      // you're allocating memory for codes
      // must be freed with free(codes);
      char*** codes = malloc(5 * sizeof(char**));
      
      for ( i = 0; i <= 4; i++ ) {
      
          // allocating memory for every element in codes
          // must be freed with free(codes[i]);
          codes[i] = malloc((i+1) * sizeof(char*));
      
          for ( j = 0; j <= i; j++ ) {
      
              // allocating memory for every element in every element in codes
              // must be freed with free(codes[i][j])
              codes[i][j] = malloc(2 * sizeof(char));
      
          }
      }
      

      所以是的,您的第二个选项是正确的。

      【讨论】:

      • +1 表示第一句话。以与分配相反的顺序释放也是一个好主意。特别是在这个多维问题中,如果不这样做,您将破坏指针并泄漏。
      【解决方案4】:

      最好不要使用嵌套的 malloc()-s,如果你可以事先计算好数组的大小的话。您应该一步分配和释放(让您的生活更轻松并减少错误的机会)。

      【讨论】:

        【解决方案5】:

        createMultiArray() 的内存布局如下:

                    codes[i]       codes[i][j]
        ***         **             *      
        +-+         +-+            +-+-+
        |0|-------->| |----------->| | | 
        +-+         +-+            +-+-+
        |1|-----+                   | | 
        +-+     |   +-+             | | 
        |2|     +-->| |             | +------------- char
        +-+         +-+             +--------------- char
        |3|         | + 
        +-+         +-+ 
        |4| 
        +-+         ....            ....
        

        现在,返回并释放您使用 free 创建的每个内存 [是的,每个 malloc() 都应该有一个 free()]

        OTOH,您确定要这样做吗?

        for ( i = 0; i <= 4; i++ ) {
            codes[i] = malloc((i+1) * sizeof(char*));
            ....
        }
        
        for i=0, malloc will create 1 memory cell
        for i=1, malloc will create 2 memory cell
        for i=2, malloc will create 3 memory cell
        for i=3, malloc will create 4 memory cell
        for i=4, malloc will create 5 memory cell
        

        这是故意的吗?

        【讨论】:

        • 我输入了codes[i] = malloc((i+1) * sizeof(char*));,因为在下一行我输入了for ( j = 0; j &lt;= i; j++ )。这样不行吗?
        • 这很好! ..我只是好奇这是否是故意的! :)
        【解决方案6】:

        不要使用如此复杂的分配方案来模拟多维数组。特别是在您的情况下,所有边界都是编译时常量。

        char (*codes)[n][m] = malloc(sizeof(char[x][n][m]));
        

        达到同样的目的,只需要一个

        free(codes);
        

        最后。如果您使用该数组的上下文甚至绑定到一个范围并且您的范围很小,您甚至可以将其直接分配为 auto 变量,甚至同时初始化它

        char codes[23][2][5] = { { { 'a', 'b'}  } };
        

        最后不需要释放。

        【讨论】:

        • 嘿,这个答案肯定会在未来帮助我!但在这种情况下,我的代码只是一个示例,我的数组的大小不是一个常数,而是在运行时确定的。谢谢;)
        • @Psyclops 只要您使用 C99,所有这些都可以在运行时发生。
        猜你喜欢
        • 2012-10-08
        • 2014-11-05
        • 1970-01-01
        • 2011-08-05
        • 2010-12-16
        • 2020-01-18
        • 2012-04-20
        • 1970-01-01
        相关资源
        最近更新 更多