如果失败的malloc?(What if malloc fails?)

2019-07-30 18:38发布

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

在这样的事情:

char* mystrdup(const char *s)  
{
    char *ab = NULL;

    while(ab == NULL) {
        ab=(char*)malloc(strlen(s)+1);  
    }

    strcpy(ab, s);
    return ab;
}

是while循环的有效检查内存分配?

Answer 1:

一般情况下,一个现代malloc()实现将返回NULL只能作为一个绝对的最后手段,并试图再次肯定不会帮助。 这将有助于唯一被释放一些内存 ,然后再次尝试。 如果您的应用程序保存的任何资源消耗,这将是他们自由的时间,然后给它一个镜头。

在某些环境中,一个有用的做法是分配的少量内存作为应急基金 。 如果malloc()永远不会返回NULL ,则可以释放一个应急基金,然后分配任何你需要的资源,能够处理错误,并优雅地退出。 这是与旧的Macintosh工具箱编程时的普遍做法; 如果malloc()返回NULL ,你可以使用的空间创建一个对话框退出之前报告的问题。



Answer 2:

在单线程程序“再次尝试”而不释放任何内存之间尝试毫无实际意义。 它只会永远循环下去。

在多线程程序,这可能“工作”,如果另一个线程并行运行突然决定释放一些自己的记忆。 在这种情况下,循环将构成经典的“忙等待”循环。 但即使在这种情况下,这样的代码有不止一个原因是非常实用价值不大。



Answer 3:

没有永不。 如果malloc返回NULL,表示有错误,你可能应该退出。



Answer 4:

没有争论为什么或什么时候这将是有益的,尝试重新分配在一个循环中可以工作,至少在Windows 64位编码,默认页面文件设置。 此外,这可能会购买更多的出奇额外的虚拟内存。 虽然,不要在一个无限循环做到这一点,而是使用重试的数量有限。 作为一个证明,试试下面的代码一种模拟泄漏1 MB的内存。 你必须在发布版本中运行它,最好不要在调试器下。

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,我得到下面的输出(与VS2013建为64的目标,在Windows 7专业测试):

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

我不知道这样的行为的确切原因,但似乎分配开始一次未能页面文件大小调整不能请求跟上。 在我的机器,页面文件从8 GB到20 GB,增长这个循环之后(在程序退出后回落到8 GB)。



Answer 5:

这是令人难以置信的可能性不大,这将做你想做的; 如果你的内存不足,忙循环,直到你获得更多的可能是令人失望的。 你应该只返回NULL给调用程序,以便它可以处理资源耗尽,无论是通过释放它不再需要存储或返回一个错误。



Answer 6:

的malloc()尝试其最佳分配内存。 如果失败,而不是重新尝试在while循环分配内存(程序可能会被卡住永远存在),试图释放一些其他进程或线程持有一些内存,如果你能,然后重试。

另一种方法是增加存储器,通过增加交换文件或寻呼存储器,在飞行中,从代码本身(但它的危险和不优选的)或手动操作的方式它内。

为了避免这样的问题,最好的方法是计算或估计对内存的需求,一边写代码本身。



Answer 7:

尝试增加堆大小(存储器用于动态分配的预留)。



文章来源: What if malloc fails?
标签: c memory malloc