【问题标题】:C freeing 2D array if malloc fail如果 malloc 失败,C 将释放 2D 数组
【发布时间】:2016-10-12 11:33:46
【问题描述】:

如果我有一个二维数组分配如下:

int** map;
map = malloc(number * sizeof(int*));
if(!(map)){
    printf("out of memory!\n");
    return 1;
}
for (int i = 0; i < number; i++){
    map[i] = malloc(number * sizeof(int));
    if (!(map[i])){
        printf("Not enough memory!\n");
        return 1;
    }
}

如果分配失败并且我们在 if 语句中输入,我应该释放映射和分配到现在的“列”吗?如果是这样,我应该怎么做?

现在我只是打印消息并返回 1 但我不确定这是否是正确的方法。

【问题讨论】:

  • 您没有二维数组。那是一个基于指针的查找表。要分配 2D 数组,您必须使用 int (*map)[number] = malloc(sizeof (int[number][number])); 或等效项。区别,即二维数组的数据分配在相邻的内存单元中,理解这一点非常重要。
  • 别忘了检查外层malloc的返回值。
  • @Lundin 哦,我不知道,除了数据分配方式不同之外,在如何使用它们/速度方面还有其他差异吗?
  • @user464502 我忘记了,已修复。谢谢
  • @JohnSmith 您使用的方法的唯一优点是它允许查找表的每个“维度”获得与其他“维度”不同的大小,并在运行时更改大小。缺点是您的方法会导致堆分段,由于缓存未命中和不必要的复杂代码导致程序慢得多,这些代码可能会导致错误和内存泄漏。此外,您的代码的实际分配时间要慢得多。

标签: c arrays malloc free


【解决方案1】:

是的,你应该 free() 否则你会泄漏内存,这在长时间运行的程序中可能很重要。

一种更简单的方法是计算所有分配的总大小,并执行单个较大的malloc(),而不是一大堆较小的。这也(可能)更快,因为堆分配可能很昂贵。

这样你只需要检查一次是成功还是失败,失败时free()什么都没有。

类似这样的:

int ** map_allocate(size_t number)
{
  int **base = malloc(number * sizeof (int *) + number * number * sizeof (int));
  if(base != NULL)
  {
    int *row = (int *) (base + number);
    for(size_t i = 0; i < number; ++i)
      base[i] = row + i * number;
  }
  return base;
}

我没有测试运行这个,但类似的东西。

【讨论】:

  • mh,对于访问量很大的大型地图,它是否仍然更快,或者从长远来看它可能会更慢,因为我每次都必须计算我的号码在哪里?如果它几乎总是更快,我实际上可能会使用类似于你的解决方案(我需要尽可能多地从我的程序执行中减少时间)
  • @JohnSmith 什么?我没有提出任何不同的数据结构,也没有什么要“计算我的号码在哪里”,无论这意味着什么,我提供的只是 allocating 数组数组的另一种方法。我很困惑。
【解决方案2】:

你可以使用:

if (!(map[i])){
    printf("Not enough memory!\n");

    while (--i>=0)
        free(map[i]);

    free(map);
    return 1;
}

【讨论】:

    【解决方案3】:

    总是在分配指针时立即将指针设置为 null。

    int **map;
    
    map = malloc(number * sizeof(int *));
    if(!map)
        goto out_of_memory;
    for(i=0;i<number;i++)
        map[i] = 0;
    
    for(i=0;i<numbers;i++)
    {
        map[i] = malloc(number * sizeof(int));
        if(!map[i])
            goto out_of_memory;
    }
    
    ...
    
    return 0;
    
    out_of_memory:
        if(map)
            for(i=0;i<number;i++)
                free(map[i]);
        free(map);
        return -1;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-07
      • 1970-01-01
      • 1970-01-01
      • 2015-06-17
      • 2022-01-05
      相关资源
      最近更新 更多