malloc in do while block

时间:2013-01-06 08:36:25

标签: c malloc

我可以将malloc放在do ... while块中以确保成功分配吗?

像:

#define STR_SIZE 1024 * 1024
char *str;
do
    str = (char *) malloc(STR_SIZE);
while ( !str );

4 个答案:

答案 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可能会真正失败。所以你必须处理这个案子。

顺便说一下,您可以考虑使用Boehm's conservative garbage collector并使用GC_malloc代替malloc而不关心其失败和free - ing。 (我认为当没有足够的内存时,Boehm的GC会中止该程序。)

答案 1 :(得分:1)

当然,如果STR_SIZE不合理,这将永远锁定您的代码。

如果您的内存非常碎片化,Malloc也会在极少数情况下失败。在这种情况下,您的代码将起作用。

答案 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会失败,语法上是正确的,但如果它在逻辑上是正确的,那么如果它有效,我会尝试编码。