我们应该检查内存分配是否失败?

我已经看到很多代码在进行分配时检查NULL指针。 这使代码变得冗长,如果没有一致地完成,只有当程序员感觉到它时,甚至不能确保程序在地址空间用完时不会崩溃。 此外,如果程序无法进行更多分配,那么它无论如何都无法完成其function,对吧?

所以我的问题是,对于大多数程序来说,根本不检查并且如果内存耗尽就让程序崩溃是不是更好? 至少代码更具可读性。

注意

我说的是在现代计算机上运行的桌面应用程序(至少2 GB的地址空间),而且绝对不会运行航天飞机,生命支持系统或BP的石油平台。 最重要的是,我在谈论使用malloc但从未真正超过5 MB内存使用量的程序。

总是检查返回值,但为了清楚起见,将malloc()包装在一个永不返回NULL的函数中是很常见的:

 void * emalloc(size_t amt){ void *v = malloc(amt); if(!v){ fprintf(stderr, "out of mem\n"); exit(EXIT_FAILURE); } return v; } 

然后,以后你可以使用

 char *foo = emalloc(56); foo[12] = 'A'; 

没有内疚。

是的,您应该检查malloc的null返回值。 即使你无法从内存分配失败中恢复,你也应该明确退出。 如果内存分配成功继续使应用程序处于不一致状态,并且可能导致应该避免的“未定义行为”。

例如,您可能最终将不一致的数据写入外部存储,这可能会阻碍下一次运行应用程序的恢复能力。 以更加可控的方式快速退出会更安全。

许多想要在分​​配失败时退出的应用程序将malloc包装在一个函数中,该函数检查返回值并在失败时显式中止。

可以说,这是C ++默认new方法在分配失败时抛出exception的一个优点。 它不需要努力退出内存分配失败。

与Dave的上述方法类似,但添加了一个宏,可以自动将文件名和行号传递给我们的分配例程,以便我们可以在发生故障时报告该信息。

 #include  #include  #define ZMALLOC(theSize) zmalloc(__FILE__, __LINE__, theSize) static void *zmalloc(const char *file, int line, int size) { void *ptr = malloc(size); if(!ptr) { printf("Could not allocate: %d bytes (%s:%d)\n", size, file, line); exit(1); } return(ptr); } int main() { /* -- Set 'forceFailure' to a non-zero value in order to observe how 'zmalloc' behaves when it cannot allocate the requested memory -- */ int bytes = 10 * sizeof(int); int forceFailure = 0; int *anArray = NULL; if(forceFailure) bytes = -1; anArray = ZMALLOC(bytes); free(anArray); return(0); } 

但如果不记录malloc失败的位置,则要进行故障排除要困难得多。

未能在XX行分配内存不仅仅是为了崩溃。

你一定要检查malloc的返回值。 有助于调试,代码变得健壮。

总是检查malloc的内存?

在托管环境中,检查malloc返回的错误现在没有多大意义。 大多数机器的虚拟地址空间为64位。 你需要花很多时间来消耗它。 您的程序很可能在完全不同的地方失败,即当您的物理+交换内存耗尽时。 在此之前它会显示出完全荒谬的性能,因为它只是交换而且用户在你到达之前很久就会触发Cntrl-C

在空指针引用上“很好地”Segfaulting将是一个明确的点,以查看调试器中的事情失败。 但在我的实践中,我从未见过失败的malloc作为原因。

在为嵌入式系统编程时,图像会完全改变。 你肯定应该检查malloc失败。

编辑:在编辑问题后澄清。 那里描述的那种程序/系统显然不是“嵌入式”的。 在那里描述的情况下,我从未见过malloc失败。

我想补充一点,即使您认为边缘情况安全或不能导致其他问题而不是崩溃,也应始终检查边缘情况。 可以利用空指针解除引用(http://uninformed.org/?v=4&a=5&t=sumry)。