【问题标题】:How to free a malloc'd 2D array in C?如何在 C 中释放 malloc 的二维数组?
【发布时间】:2019-11-04 04:33:05
【问题描述】:

以下是我的代码,我无法弄清楚释放二维数组时哪里出错了。 我知道错误发生在这一行:free(arr[i]);而且我也知道我必须先执行此循环以释放每个整数,然后再释放整个数组。任何人都可以在这里发现错误吗?我没有遇到编译错误,但是一旦运行我的可执行文件,free 函数就会有大量的回溯输出。

#include <stdio.h>
#include <stdlib.h>

int main()
{
        int h = 4;
        int w = 2;
        int i, j;

        int **arr = (int**)malloc(sizeof(int*) * h);
        arr[0] = (int*)malloc(sizeof(int) * w * h);

        for (i=1; i<h; i++)
        {
                arr[i] = arr[0] + (w*i);
        }

        int count = 0;
        for (i=0; i<h; i++)
        {
                for (j=0; j<w; j++)
                {
                        arr[i][j] = count++;
                }
        }


        for (i=0; i<h; i++)
        {
                for (j=0; j<w; j++)
                {
                        printf("Array[%d][%d] = %d ", i, j, arr[i][j]);
                }
                printf("\n");
        }

        for (i=0; i<h; i++)
        {
                free(arr[i]);
        }

        free(arr);

        /*printf("\nAfter freeing the array it becomes:\n");
        for (i=0; i<h; i++)
        {
                for (j=0; j<w; j++)
                {
                        printf("Array[%d][%d] = %d ", i, j, arr[i][j]);
                }
                printf("\n");
        }*/

}

【问题讨论】:

  • 你打电话给malloc 两次但你打电话给free 两次以上......他们必须匹配
  • 你是说我在循环中多次调用 free 吗?我应该如何正确地做到这一点?在我在网上查看的所有其他地方都需要这个循环来释放每个整数
  • @camillesmith99 主人,他是 M,M,意味着你在循环中调用 free 时不会在循环中调用任何 mallocs。也就是说,代码部分看起来只是一个传真,没有掌握其底层逻辑。
  • 在这部分代码中,我为 (i=1; i
  • 谢谢,这有帮助。以我构建它的方式释放数组的正确方法是:free(arr[0]); //释放内层 free(arr); //为我调用的每个 malloc 释放外层 One?

标签: c arrays multidimensional-array c99


【解决方案1】:

您只为arr[0] = (int*)malloc(sizeof(int) * w * h); 分配内存,但在释放分配的空间时,您最多释放h 计数,for (i=0; i&lt;h; i++){free(arr[i]);}。您也应该使用相同的循环以这种方式分配。

【讨论】:

    【解决方案2】:

    你在调用中分配的内存 arr[0] = (int*)malloc(sizeof(int) * w * h); 对于整个二维数组来说已经足够了。如果您想使用这种方法,即在一次 malloc 调用中为 2D 数组分配内存,您可以通过将返回的指针转换为指向 w 元素的数组的指针来实现。然后,您还可以通过一次调用 free 来释放内存。无需使用 for 循环。请参阅下面的代码。

    int main()
    {
        int h = 4;
        int w = 2;
        int i, j;
    
        int (*arr)[w] = (int(*)[w])malloc(sizeof(int)*h*w); // pointer to array of w ints
    
        int count = 0;
        for (i=0; i<h; i++) {
            for (j=0; j<w; j++) {
                arr[i][j] = count++;
            }
        }
    
        for (i=0; i<h; i++) {
            for (j=0; j<w; j++) {
                printf("Array[%d][%d] = %d ", i, j, arr[i][j]);
            }
            printf("\n");
        }
    
        free(arr);  //<-- free the 2D array in a single free
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      当你使用你的 malloc 时,你只分配数组的第一个位置

      arr[0] = (int*)malloc(sizeof(int) * w * h);

      这意味着当您必须释放内存时,您需要先调用free(arr[0]),然后再调用free(arr)

      这不会给你一个错误。

      无论如何,我不认为这是你想要做的。您可能需要更多以下方面的解决方案:

      int **arr = (int**)malloc(sizeof(int*) * h);
      
      for (int i = 1; i < h ; ++i){
           arr[i] = (int*)malloc(sizeof(int) * w); // with the correct size you want
      }    
      

      这将在数组中分配 h 指针以供使用,然后您可以像在示例中那样释放内存

      编辑:请注意,就像@AndrewHenle 在他的评论中正确指出的那样,此解决方案不会分配 true 2D 数组,而只是分配指向数组的指针数组。有关正确分配二维数组的方法,请参阅this 相关问题

      【讨论】:

      • 您可能需要更多在线解决方案 不。只有两个malloc() 调用的解决方案效率更高。在循环中多次调用malloc() 不是“二维数组”——它是指向一维数组的指针数组。对于 true 动态分配的多维数组,请参阅stackoverflow.com/questions/42094465/…
      • @AndrewHenle 我知道。我从来没有在我的答案中写过我使用二维数组的任何地方,我写道我的答案“将在数组中分配h 指针以供使用”,这正是你写的“指向一维数组的指针数组”。在他的示例中给出他是如何尝试free 内存的,我认为他想要一个更符合我所写内容的解决方案,而不是真正的二维数组。我将在我的答案中添加一个编辑以更好地反映这一点
      【解决方案4】:
      //for (i=0; i<h; i++) { free(arr[i]); }//error
      free(arr[0]);  //true
      
      free(arr);
      

      【讨论】:

      • 只有代码的答案通常被认为是低质量的。您能否为您的答案添加解释。
      • 我不懂英语
      猜你喜欢
      • 1970-01-01
      • 2011-08-05
      • 2021-03-05
      • 1970-01-01
      • 2020-01-18
      • 2015-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多