我可以将malloc放在do ... while块中以确保成功分配吗?
像:
#define STR_SIZE 1024 * 1024
char *str;
do
str = (char *) malloc(STR_SIZE);
while ( !str );
答案 0 :(得分:8)
它可能不起作用,因为malloc
很少失败,当资源耗尽时它会失败,而这些将很快就无法使用。
malloc
可以获得更多资源的唯一常见情况是,如果某个其他大进程释放大量内存,并且很少发生并且可能永远不会发生;如果你关心在你的循环中添加至少一个sleep
,并准备在malloc
真正失败并且总是返回NULL
时处理这个案例。
更好的做法是测试malloc
结果并退出并显示失败和错误消息,例如
char* str = malloc(STR_SIZE);
if (!str) {
perror("malloc failed for str");
exit (EXIT_FAILURE);
}
每个程序都应该处理malloc
失败时的情况(通常是通过退出并显示错误消息)。
许多程序在xmalloc
失败时调用exit
- abort
- s或malloc
- s的函数,并在成功时返回分配的区域功能
使用malloc故障(即正在做某事能够继续执行)明智地处理非常困难。有些程序可能是free
其他一些全球数据。实际上,这相当于实现了一些专门的garbage collection机制。某些服务器可能只是失败当前请求(并且应该非常谨慎地执行此操作,释放当前失败请求使用的所有资源)。
当您需要更多可用资源时,malloc
可能会真正失败。所以你必须处理这个案子。
GC_malloc
代替malloc
而不关心其失败和free
- ing。 (我认为当没有足够的内存时,Boehm的GC会中止该程序。)
答案 1 :(得分:1)
当然,如果STR_SIZE
不合理,这将永远锁定您的代码。
答案 2 :(得分:1)
正如其他答案所指出的,您的代码存在缺陷。然而,背后的想法并非完全不合理。
处理malloc
失败的经典方法是让程序退出,如Basile's answer中所述。检查malloc
的返回值的代码通常放在名为xmalloc
等的通用包装函数中,并始终用于代替malloc
。这很容易实现和推理,但它并非没有缺陷。它对于短命令的命令行程序(例如通常从Unix shell调用的程序)很有意义,但是对于程序不适合立即丢失的交互式程序来说它是失败的,即使它已经耗尽内存。它也不适用于库代码,因为使用该库的程序可能不希望该进程仅因为单个分配失败而退出。
如果内存问题很可能不是由程序活动引起的,那么重新分配是有意义的。例如,多进程HTTP服务器可能不希望拒绝请求并在单个内存分配失败时立即结束进程。但是,一个好的实现方法是:1)注意在请求之间休眠以避免繁忙循环并为系统提供恢复的机会,以及2)确保在多次迭代后进程退出,以防它是进程本身导致分配失败。例如:
void *safe_malloc(size_t howmuch)
{
int i = 0;
while (i++ < 10) {
void *ptr = malloc(howmuch);
if (ptr)
return ptr;
sleep(i);
}
perror("malloc");
exit(EXIT_FAILURE);
}
此方法已用于服务器,例如现已过时的phttpd网络服务器。
交互式应用程序中malloc
失败的另一种方法是Emacs使用的方法:在启动时分配固定数量的内存并保存以供日后使用。当内存分配失败时,将释放释放内存并引发Lisp级异常,从而放弃当前操作。将向用户显示警告消息,说明情况。释放的内存使程序能够继续工作足够长的时间,以便用户在Emacs关闭之前保存其工作。
答案 3 :(得分:-1)
你可以,虽然它是一个罕见的malloc会失败,语法上是正确的,但如果它在逻辑上是正确的,那么如果它有效,我会尝试编码。