在什么情况下malloc可以返回NULL?

Ran*_*ber 28 c malloc memory-management

它从来没有发生在我身上,而且我已经编程多年了.

有人能给我一个非平凡程序的例子,其中malloc实际上不起作用吗?

我不是在谈论内存耗尽:我正在寻找一个简单的情况,当你只分配一个由用户给出的绑定大小的内存块时,假设一个整数,导致malloc失败.

pax*_*blo 25

你需要在嵌入式系统中做一些工作,你经常会在那里返回NULL :-)

在现代大容量地址空间和后备存储系统中耗尽内存要困难得多,但在处理大量数据的应用程序中,例如GIS或内存数据库,或者错误代码导致内存泄漏.

但是,你以前从未体验过它并不重要 - 标准说它可能发生,所以你应该迎合它.在过去的几十年里,我也没有被汽车击中,但这并不意味着我没有首先徘徊在道路上.

并重新编辑:

我不是在谈论内存耗尽,......

非常定义内存耗尽是malloc不是给你所需的空间.无论是分配所有可用内存还是堆碎片导致无法获得连续块,即使内存区域中所有空闲块的聚合更高,或者使用符合标准的功能人为地限制地址空间使用也无关紧要:

void *malloc (size_t sz) { return NULL; }
Run Code Online (Sandbox Code Playgroud)

C标准不区分故障模式,只是成功或失败.

  • 布莱恩,我认为我的答案已经涵盖了这一点.内存耗尽被定义为`malloc`无法为您提供所需内容.无论你是真的完全没有内存还是你要求60个字节而且分配器有10亿个30字节的块无法合并,这并不重要.在这两种情况下都很耗尽.在任何情况下,一个`malloc`每十次调用它就会返回NULL,无论它有多少内存(由一个真正的虐待狂写的)仍然符合标准. (2认同)

Use*_*ess 19

是.

只需尝试malloc比系统提供的更多内存(通过耗尽地址空间或虚拟内存 - 以较小者为准).

malloc(SIZE_MAX)
Run Code Online (Sandbox Code Playgroud)

可能会这样做.如果没有,重复几次直到你用完为止.

  • 我的第一台计算机是一个带有56KB RAM的8位系统.`malloc()`经常返回`NULL`. (6认同)
  • 对不起,显然我应该发布一个非常重要的程序,分配数亿个合理大小的对象是有充分理由的,这显然会产生完全相同的结果.它既不可读,简洁又不平凡! (5认同)
  • 谢谢,但这非常微不足道.我说的是一个简单的例子,我们只分配了一段内存.它还能失败吗?看我的编辑 (3认同)
  • 这个答案就是内存耗尽的情况.海报要求malloc()返回0并且内存不用尽的情况. (2认同)

Rus*_*ssS 9

任何用c编写的程序都需要动态分配比OS当前允许的内存更多的内存.

为了好玩,如果您使用的是ubuntu类型

 ulimit -v 5000
Run Code Online (Sandbox Code Playgroud)

您运行的任何程序很可能会崩溃(由于malloc失败),因为您已将任何一个进程的可用内存量限制为精简量.


Phi*_*lip 8

除非您的内存已经完全保留(或严重碎片化),否则malloc()返回NULL-pointer 的唯一方法是请求大小为零的空间:

char *foo = malloc(0);
Run Code Online (Sandbox Code Playgroud)

引用C99标准,§7.20.3,第1小节:

如果请求的空间大小为零,则行为是实现定义的:返回空指针,或者行为就像大小是非零值一样,除了返回的指针不应用于访问对象.

换句话说,malloc(0)可以返回NULL指向零分配字节的-pointer或有效指针.


Mic*_*gan 5

选择任何平台,尽管嵌入式可能更容易。 malloc(或new)大量 RAM(或随着时间的推移泄漏 RAM,甚至使用简单的算法将其碎片化)。繁荣。 当“坏”事情发生时,malloc它会偶尔回来找我。NULL

回应您的编辑。是的,又是。随着时间的推移,内存碎片可能会导致即使是单个分配也int可能会失败。另请记住,它malloc不仅为 分配 4 个字节int,而且还可以获取所需的空间。它有自己的簿记内容,并且通常会最少占用 32-64 字节。


Hot*_*cks 5

在一个或多或少的标准系统上,使用标准的单参数 malloc,存在三种可能的故障模式(我能想到的):

  1. 请求的分配大小是不允许的。例如,某些系统可能不允许分配 > 16M,即使有更多存储可用。

  2. 无法在堆中找到具有默认边界的所请求大小的连续空闲区域。可能仍然有很多堆,但只是不够。

  3. 分配的堆总数已超过某些“人为”限制。例如,即使单个组合堆中有 200M 的空闲空间可供“系统”使用,用户也可能被禁止分配超过 100M 的空间。

(当然,您可以得到 2 和 3 的组合,因为某些系统会随着堆的增长向堆分配不连续的地址空间块,从而对块的总数设置“堆大小限制”。)

请注意,某些环境支持其他 malloc 参数,例如对齐和池 ID,这些参数可能会添加自己的变化。