c-malloc返回null时的动态数组清理



我想知道什么是清理在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))i = 3返回了null。我们已经为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);

简而言之:

由于您有不同的函数用于分配内存,因此需要相应地调用它们的对应解除分配函数:

  • malloc()calloc()realloc()需要通过调用free()来解除分配
  • X* x = new X();需要与delete x;解除分配
  • X** x = new X[10];需要与delete[] x;解除分配

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

  • std::vector<X> x;

或类似的智能指针

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

让您不再关心必要的记账,而是正确地平衡分配/解除分配操作。


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

如果您使用了错误的动态内存去/分配函数对,则没有定义标准的错误处理。

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

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);的单个调用就足够了。

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

相关内容

  • 没有找到相关文章