为什么malloc()或new永远不会返回NULL?

时间:2013-05-21 15:57:48

标签: c++ c memory-management

我正在编写一个需要大量内存用于缓存的应用程序,正如我所描述的那样here。现在我正在玩一些malloc / new结构来弄清楚我是如何实现它的。我做了一个奇怪的观察:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
  while(1) {
    char *foo = (char*)malloc(1024);// new char[1024];
    if(foo == NULL) { 
      printf("Couldn't alloc\n");
      fflush(stdout);
      return 0;
    }
  }
  return 0;
}

为什么永远不会达到printf?如果我的系统内存不足,则称malloc返回NULL,如here所述。但我总是收到SIGKILL(我正在使用linux ......)。

4 个答案:

答案 0 :(得分:23)

默认情况下,Linux通常使用机会内存分配方案,这意味着内核会为您提供一个在首次使用之前不会分配的有效地址。

请参阅:

根据这些回复,您可以使用echo 2 > /proc/sys/vm/overcommit_memory关闭此功能。

据我所知,这是在您不必使用所分配的所有内存的假设下完成的。我不能说我个人曾经分配过至少一次不触及的空间,所以我很想知道这会影响现实生活中的表现......

关于SIGKILL失败,您调用的每个malloc仍然为每个调用分配一些内存。最终你可能会用malloc开销填满你的记忆,从而唤起内存终止杀戮功能的愤怒。这是否是问题,或者过度使用政策是否仍然分配了一小部分所需空间是一个很好的问题。

答案 1 :(得分:6)

通常,Linux会根据您的请求分配尽可能多的(虚拟)内存,并且只在需要时为其分配物理内存。如果系统耗尽了物理内存,那么它会开始杀死进程以释放一些内存。

这意味着malloc将成功,除非请求是荒谬的,但是你的进程(或其他一些)可能会因使用内存而被杀死。

有关详细信息,请参阅malloc的联机帮助页及其参考:

  

默认情况下,Linux遵循乐观的内存分配策略。          这意味着当malloc()返回非NULL时,无法保证          内存确实可用。如果事实证明了          系统内存不足,一个或多个进程将被杀死          OOM杀手。有关更多信息,请参阅的说明          / {/ 1}}中的/ proc / sys / vm / overcommit_memory和/ proc / sys / vm / oom_adj,以及          内核源文件Documentation / vm / overcommit-accounting。

(当然proc(5)除非你使用无投掷版本,否则不会返回null。

答案 2 :(得分:2)

如果无法满足请求的分配,

malloc将返回NULL但也许您应该尝试从分配大量空间。

请参阅here

  

在linux上,调用malloc()时获取错误的唯一方法是   禁用内存过量使用。在常规的Linux系统上,这就是   方式,malloc()返回NULL。如果一个冰球过程到达   那一点,无论如何它已经搞砸了它无法做任何事情   有意义的:任何源读取都将失败(refbuf alloc),任何日志打印   也将失败(printf也使用malloc),所以它也可能放弃和   叫abort()。

答案 3 :(得分:0)

如果操作系统让你的程序运行那么久,那么

Malloc将返回NULL。但是在malloc有机会运行操作系统之前就会杀死你的进程。

如果它检测到您正在编写分配给您的流程的外部内存页面,就会杀死您的流程。