在出错之后,在二维数组中释放内存时遇到了一些奇怪的事情。
案例1:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int main(void)
{
int **a = NULL;
int i;
int j;
if(!(a = calloc(5, sizeof(int *))))
{
printf("Error, could not allocate memory for a!\n");
exit(EXIT_FAILURE);
}
for(i = 0; i < 5; i++)
{
if(i != 2)
{
if(!(a[i] = calloc(3, sizeof(int))))
{
printf("Error, could not allocate memory for a[%d]!\n",i);
for(j = 0; j < i; j++)
{
free(a[j]);
}
free(a);
}
}
else
{
if(!(a[i] = calloc(MAX_INT * 1000, sizeof(int))))
{
printf("Error, could not allocate memory for a[%d]\n", i);
for(j = 0; j < i; j++)
{
free(a[j]);
}
free(a);
}
}
}
return 0;
}
案例2:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int main(void)
{
int **a = NULL;
int i;
int j;
if(!(a = calloc(5, sizeof(int *))))
{
printf("Error, could not allocate memory for a!\n");
exit(EXIT_FAILURE);
}
for(i = 0; i < 5; i++)
{
if(i != 2)
{
if(!(a[i] = calloc(3, sizeof(int))))
{
printf("Error, could not allocate memory for a[%d]!\n",i);
for(j = 0; j <= i; j++)
{
free(a[j]);
}
free(a);
}
}
else
{
if(!(a[i] = calloc(MAX_INT * 1000, sizeof(int))))
{
printf("Error, could not allocate memory for a[%d]\n", i);
for(j = 0; j <= i; j++)
{
free(a[j]);
}
free(a);
}
}
}
return 0;
}
两种情况之间的唯一区别在于,在情况1中,当出现问题时分配内存(我故意有一个大的分配导致它在i == 2时失败)I循环从j = 0到j&lt; i和在情况2中,当释放a [j]时,I从j = 0循环到j&lt; = i。既没有给我一个编译器错误或警告,并且在运行valgrind时都没有导致问题或泄漏,所以我只是想知道哪个是正确的方法呢?我认为这是案例1,因为元素i的分配失败了,所以没有实际分配内存,这意味着没有必要释放它,但是valgrind没有泄漏让我第二次猜测自己。谢谢!
答案 0 :(得分:3)
为了输入分配失败的if
分支a[i]
必须设置为NULL
指针。 Since passing NULL
pointer to free
is well-defined in the C standard,包括或排除循环中的a[i]
没有任何区别。
但是两个版本都有相同的问题:当在外部for
循环内发生故障时,您不会在清理后退出程序,让分配继续。这应该通过在exit(EXIT_FAILURE)
之后添加对free(a)
的调用来解决。