如果malloc失败怎么办?

如果malloc分配失败,我们应该再试一次吗?

在这样的事情:

 char* mystrdup(const char *s) { char *ab = NULL; while(ab == NULL) { ab=(char*)malloc(strlen(s)+1); } strcpy(ab, s); return ab; } 

while循环对检查内存分配有效吗?

通常,现代malloc()实现将仅作为绝对的最后手段返回NULL ,并且再次尝试肯定无济于事。 唯一有用的就是释放一些记忆然后再试一次。 如果您的应用程序拥有任何消耗性资源,那么这将是释放它们的时间,然后再给它一次。

在某些环境中,一种有用的做法是将少量内存分配为雨天基金 。 如果malloc() 确实返回NULL ,你可以释放那个下雨天的基金,然后分配你需要的任何资源来处理错误并优雅地退出。 这是使用旧的Macintosh Toolbox编程时的常见做法; 如果malloc()返回NULL ,则可以使用该空间创建一个对话框,以在退出之前报告问题。

在单线程程序中“再次尝试”而不会在尝试之间释放任何内存,这没有任何实际意义。 它将永远循环。

在multithreading程序中,如果另一个并行运行的线程突然决定释放它自己的一些内存,这可能会“正常”。 在这种情况下的循环将构成经典的“忙等待”循环。 但即使在这种情况下,这样的代码由于更多原因而没有实际价值。

没有永不。 如果malloc返回NULL,则表示错误,您应该中止。

在没有争论为什么或什么时候这有用的情况下,尝试在循环中重新分配可能会起作用,至少在具有64位代码的Windows和默认页面文件设置上。 此外,这可能会出乎意料地购买更多额外的虚拟内存。 虽然,不要在无限循环中执行此操作,而是使用有限数量的重试。 作为certificate,请尝试以下代码模拟泄漏1 Mb的内存。 您必须在Release版本中运行它,最好不要在调试器下运行它。

 for (int i = 0; i < 10; i++) { size_t allocated = 0; while (1) { void* p = malloc(1024 * 1024); if (!p) break; allocated += 1; } //This prints only after malloc had failed. std::cout << "Allocated: " << allocated << " Mb\n"; //Sleep(1000); } 

在我的具有8 Gb RAM和系统管理页面文件的计算机上,我得到以下输出(使用VS2013 for x64 target构建,在Windows 7 Pro上测试):

 Allocated: 14075 Mb Allocated: 16 Mb Allocated: 2392 Mb Allocated: 3 Mb Allocated: 2791 Mb Allocated: 16 Mb Allocated: 3172 Mb Allocated: 16 Mb Allocated: 3651 Mb Allocated: 15 Mb 

我不知道这种行为的确切原因,但是一旦页面文件resize无法跟上请求,似乎分配开始失败。 在我的机器上,页面文件在此循环后从8 gb增长到20 Gb(在程序退出后降回到8 Gb)。

这不可能达到你想要的效果; 如果你内存不足,忙碌循环直到你获得更多可能会令人失望。 您应该只将NULL返回给调用程序,以便它可以通过释放不再需要的内存或返回错误来处理资源耗尽。

malloc()尽力分配内存。 如果它失败了,而不是重新尝试在while循环中分配内存(程序可能永远卡在那里),尝试释放一些其他进程或线程持有的内存,如果可以,然后重试。

另一种选择是增加内存,通过增加交换文件或分页内存,在代码本身内(但危险且不可取)或手动操作。

避免此类问题的最佳方法是在编写代码本身时计算或估计内存需求。

尝试增加堆大小(为动态分配留出的内存)。