当malloc返回null时动态数组清理

时间:2016-05-23 21:06:44

标签: c memory-management memory-leaks null malloc

我想知道清理在2D阵列创建失败期间已经分配的内存的最佳方法是什么。

int** a = (int**)malloc(rows * sizeof(int*));
for (int i = 0; i != rows; ++i)
    a[i] = (int*)malloc(columns * sizeof(int));

for (int i = 0; i != rows; ++i)
    free(a[i]);

free(a);

上面的示例代码应该像魅力一样。但是malloc可以返回null,而上述代码何时无法处理问题。我们怎样才能保护这种情况呢?

(int*)malloc(columns * sizeof(int))null返回i = 3。我们已经为int** aa[0]a[1]a[2]分配了空间。

这是我目前的做法。丑陋,不确定是否正确。这就是我向你寻求帮助的原因。

int rows;
int columns;
scanf("%d", &rows);
scanf("%d", &columns);

int** a = (int**)malloc(rows * sizeof(int*));
if (!a)
{
    printf("Cannot allocate enough space."); // nothing to clean up here
    return 1; // to make example easier
}

int i;
bool arrayCreated = true;

for (i = 0; i != rows; ++i)
{
    int* tmp = (int*)malloc(columns * sizeof(int));
    if (!tmp) // malloc returned null
    {
        arrayCreated = false; // let's mark that we need to do some cleanup
        break;
    }
    a[i] = tmp;
}

if (!arrayCreated) // creation failed, clean up is needed
{
    for (int j = 0; j <= i; ++j)
        free(a[j]);
}
else
{
    for (int i = 0; i != rows; ++i)
        free(a[i]);
}

free(a);

3 个答案:

答案 0 :(得分:2)

简而言之:

由于您使用不同的函数来分配内存,因此您需要相应地调用其对应的释放函数:

    需要通过调用malloc() 取消分配
  • calloc()realloc()free()
  • X* x = new X();需要使用delete x;
  • 取消分配
  • X** x = new X[10];需要使用delete[] x;
  • 取消分配

c ++中的惯用方法是使用容器

  • std::vector<X> x;

smart pointer喜欢

  • std::unique_ptr<X> x = std::make_unique<X>();

赎回您关注必要的簿记以正确平衡分配/解除分配操作。

  

请注意,这是一个关于此类特定情况下的错误处理的理论问题。我想强调前两个案例是针对C而不是C ++。

如果您使用错误的动态内存解除/分配功能对,则无法定义标准错误处理。

如上所述,他们需要像所描述的那样配对。其他任何东西都称为未定义的行为。

答案 1 :(得分:1)

int** b = (int**)calloc(sizeof(int*) * rows, sizeof(int*));

这不正确,calloc的第一个参数是“要分配的元素数”。

应该是

int** b = (int**)calloc(rows, sizeof(int*)); /* No need to cast in C */
  

在C和C ++中创建多维数组的安全方法是什么?   对于这种情况?

在C中(为了避免分割),应将实际的2D动态数组声明为

int (*arr)[columns]; /* A pointer to an array of n ints */

和(m)使用

分配
arr = malloc(sizeof(int [rows][columns]));

arr = calloc(rows, sizeof(int[columns]));

通过这种方式,对free(arr);的单次调用就足够了。

答案 2 :(得分:0)

我不确定C,但是C ++;删除[]就足够了。