我想知道清理在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** a
和a[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);
答案 0 :(得分:2)
简而言之:
由于您使用不同的函数来分配内存,因此您需要相应地调用其对应的释放函数:
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 ++。
如果您使用错误的动态内存解除/分配功能对,则无法定义标准错误处理。
如上所述,他们需要像所描述的那样配对。其他任何东西都称为未定义的行为。
答案 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 ++;删除[]就足够了。