c - 为二维数组分配内存出错时如何正确释放
问题描述
在出现问题后释放二维数组中的内存时,我遇到了一些奇怪的事情。
情况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;
}
案例二:
#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 时失败)我从 j = 0 循环到 j < i 并且以防万一2 释放 a[j] 时,我从 j = 0 循环到 j <= i。通过 valgrind 运行时既不会给我一个编译器错误或警告,也不会导致问题或泄漏,所以我只是想知道哪种方法是正确的?我认为是第一种情况,因为元素分配失败,因此实际上没有分配内存,这意味着没有必要释放它,但是 valgrind 没有泄漏让我再次猜测自己。谢谢!
解决方案
为了进入if
分配失败的分支,a[i]
必须设置NULL
指针。由于在 C 标准中传递NULL
指针free
是明确定义的,因此在循环中包含或排除a[i]
没有区别。
但是,两个版本都有相同的问题:当故障发生在外for
循环内部时,清理后您不会退出程序,让分配继续。这应该通过添加对exit(EXIT_FAILURE)
after的调用来解决free(a)
。
推荐阅读
- python - 代码打印“n”而不是“if”。我不知道为什么会这样
- macos - 来自 x86_64 程序集匿名函数的总线错误
- json - 使用 Python 3 将文本文件中的 Json 字符串转换为 Json 文件
- reactjs - 是否可以在高阶组件中从 HOC 渲染中的渲染中排除某些包装的组件
- json - Windows Batch - 为 ffmpeg 处理提取值
- php - 如何使用 php、dom 文档和 xpath 获取内部 div 类名的数组?
- scala - Scala Spark Convert Dataframe 并从每一行获取所有唯一 ID 及其类型
- javascript - 在 rt.t_start 和 rt.end 相等的情况下看到很长的 BoomerangJS t_done 时间
- python - 所有按钮框和文本都是黑色的
- javascript - 如何在D3中拖放一个圆圈?