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标准不区分故障模式,只是成功或失败.
Use*_*ess 19
是.
只需尝试malloc
比系统提供的更多内存(通过耗尽地址空间或虚拟内存 - 以较小者为准).
malloc(SIZE_MAX)
Run Code Online (Sandbox Code Playgroud)
可能会这样做.如果没有,重复几次直到你用完为止.
任何用c编写的程序都需要动态分配比OS当前允许的内存更多的内存.
为了好玩,如果您使用的是ubuntu类型
ulimit -v 5000
Run Code Online (Sandbox Code Playgroud)
您运行的任何程序很可能会崩溃(由于malloc失败),因为您已将任何一个进程的可用内存量限制为精简量.
除非您的内存已经完全保留(或严重碎片化),否则malloc()
返回NULL
-pointer 的唯一方法是请求大小为零的空间:
char *foo = malloc(0);
Run Code Online (Sandbox Code Playgroud)
引用C99标准,§7.20.3,第1小节:
如果请求的空间大小为零,则行为是实现定义的:返回空指针,或者行为就像大小是非零值一样,除了返回的指针不应用于访问对象.
换句话说,malloc(0)
可以返回NULL
指向零分配字节的-pointer或有效指针.
选择任何平台,尽管嵌入式可能更容易。 malloc
(或new
)大量 RAM(或随着时间的推移泄漏 RAM,甚至使用简单的算法将其碎片化)。繁荣。 当“坏”事情发生时,malloc
它会偶尔回来找我。NULL
回应您的编辑。是的,又是。随着时间的推移,内存碎片可能会导致即使是单个分配也int
可能会失败。另请记住,它malloc
不仅为 分配 4 个字节int
,而且还可以获取所需的空间。它有自己的簿记内容,并且通常会最少占用 32-64 字节。
在一个或多或少的标准系统上,使用标准的单参数 malloc,存在三种可能的故障模式(我能想到的):
请求的分配大小是不允许的。例如,某些系统可能不允许分配 > 16M,即使有更多存储可用。
无法在堆中找到具有默认边界的所请求大小的连续空闲区域。可能仍然有很多堆,但只是不够。
分配的堆总数已超过某些“人为”限制。例如,即使单个组合堆中有 200M 的空闲空间可供“系统”使用,用户也可能被禁止分配超过 100M 的空间。
(当然,您可以得到 2 和 3 的组合,因为某些系统会随着堆的增长向堆分配不连续的地址空间块,从而对块的总数设置“堆大小限制”。)
请注意,某些环境支持其他 malloc 参数,例如对齐和池 ID,这些参数可能会添加自己的变化。