我应该检查 malloc() 是不是成功?
Posted
技术标签:
【中文标题】我应该检查 malloc() 是不是成功?【英文标题】:Should I check if malloc() was successful?我应该检查 malloc() 是否成功? 【发布时间】:2015-01-06 01:25:11 【问题描述】:是否应该在每个malloc()
之后检查一次是否成功? malloc()
是否有可能失败?然后会发生什么?
在学校我们被告知我们应该检查,即:
arr = (int) malloc(sizeof(int)*x*y);
if(arr==NULL)
printf("Error. Allocation was unsuccessful. \n");
return 1;
这方面的做法是什么?我可以这样做吗:
if(!(arr = (int) malloc(sizeof(int)*x*y))
<error>
【问题讨论】:
理论上是的。实际上,如果 malloc 失败,操作系统可能即将崩溃。 PS:你的第二个例子比第一个更难阅读,应该被代码审查拒绝。arr = (int) malloc(...)
错误,malloc
返回一个指针。除此之外:是的,您应该检查它是否失败,因为它可能会失败。 Also, casting its return value is harmful.
1.你不需要演员表。 2. 是的,检查 - 为什么不
@SteveWellens 我会说在理论上和实践中都是肯定的,尤其是在分配大缓冲区时。
@AlexD - 是的。但是如果你分配的缓冲区太大以至于 malloc 可能会失败,那么我会说重新设计是为了。
【参考方案1】:
这主要只是增加了现有的答案,但我知道你来自哪里,如果你做了很多内存分配,你的代码最终看起来很丑陋,所有的 malloc 错误检查。
就我个人而言,我经常使用永远不会失败的小型 malloc 包装器来解决这个问题。除非您的软件是一个弹性的、安全的关键系统,否则无论如何您都无法有效地解决 malloc 失败的问题,因此我建议您这样做:
static inline void *MallocOrDie(size_t MemSize)
void *AllocMem = malloc(MemSize);
/* Some implementations return null on a 0 length alloc,
* we may as well allow this as it increases compatibility
* with very few side effects */
if(!AllocMem && MemSize)
printf("Could not allocate memory!");
exit(-1);
return AllocMem;
这至少可以确保您收到错误消息并清除崩溃,并避免所有大量错误检查代码。
对于可能失败的函数的更通用的解决方案,我也倾向于实现一个简单的宏,例如:
#define PrintDie(...) \
do \
\
fprintf(stderr, __VA_ARGS__); \
abort(); \
while(0)
然后允许您将函数运行为:
if(-1 == foo()) PrintDie("Oh no");
这为您提供了一个衬里,在启用适当检查的同时再次避免了大容量。
【讨论】:
您的PrintDie
应该调用abort
,而不是exit
。因为它更容易调试(在 Linux 上,您甚至会得到一个 core
转储,您可以使用 gdb
进行事后分析)
@BasileStarynkevitch 谢谢,完全忘记了 abort,现在更改示例以使用它。
if(NULL == AllocMem)
是错误的测试。使用MemSize == 0
,接收malloc()
返回值NULL
是 兼容行为,而不是分配失败。更改为 if(NULL == AllocMem && MemSize != 0)
可以解决此问题。
@chux 你说得对,这是大多数实现的理想行为,正如它所说的(在 C99 和 C11 中),标准中有点棘手:“如果请求的空间大小是零,行为是实现定义的”(7.22.3 P1,ISO C11)。但是,您建议的是许多编译器中的常见实现,因此我将在代码中添加一个带有注释的检查。谢谢。
@Ayxan 它看起来像。虽然我以前从未见过 xmalloc,因为我从未在 BSD 上开发过。看起来像一个有用的功能。谢谢你的信息。【参考方案2】:
无需投射malloc()
。可以,但是需要检查malloc()
是否成功。
假设malloc()
失败,并且您试图访问指针,认为内存分配会导致崩溃,因此最好在访问指针之前捕获内存分配失败。
int *arr = malloc(sizeof(*arr));
if(arr == NULL)
printf("Memory allocation failed");
return;
【讨论】:
在迂腐的注解中,这个答案提倡“检查 malloc() 是否成功”——这是一个好主意。但随后它显示了如何检查malloc(sizeof(int))
的结果,而不是 OP 的malloc(sizeof(int)*x*y)
。对NULL
进行测试对于这个sizeof(int)
来说就足够了,但对于OP 的sizeof(int)*x*y
来说是错误的。如果x*y
--> 0,NULL
返回是兼容代码,并不表示内存分配。最好使用if(arr == NULL && x != 0 && y != 0)
。以上是关于我应该检查 malloc() 是不是成功?的主要内容,如果未能解决你的问题,请参考以下文章