我可以依赖malloc返回NULL吗?

fre*_*low 17 c memory malloc error-handling

我在Unix系统上看到,malloc即使内存实际上不可用,也可以返回非NULL指针,并且稍后尝试使用内存将触发错误.由于我无法通过检查NULL来捕获这样的错误,我想知道检查NULL是多么有用?

Herb Sutter说,处理C++内存错误是徒劳的,因为系统会在实际发生异常之前很长时间内进行分页痉挛.这也适用malloc吗?

Ant*_*ala 32

引用Linux手册:

默认情况下,Linux遵循乐观的内存分配策略.这意味着当malloc()返回非时NULL,不能保证内存确实可用.这是一个非常糟糕的错误.如果事实证明系统内存不足,臭名昭着的OOM杀手就会杀死一个或多个进程.如果在不太可能突然丢失一些随机选择的进程的情况下使用Linux,而且内核版本足够新,可以使用如下命令关闭这种过度使用的行为:

# echo 2 > /proc/sys/vm/overcommit_memory
Run Code Online (Sandbox Code Playgroud)

您应该检查NULL返回,特别是在32位系统上,因为进程地址空间可能在RAM之前耗尽:例如,在32位Linux上,用户进程可能具有2G-3G的可用地址空间而不是4G总RAM.在64位系统上检查malloc返回代码可能毫无用处,但无论如何都可能被视为良好实践,它确实使您的程序更具可移植性.并且,请记住,取消引用空指针肯定会杀死您的进程; 与此相比,一些交换可能不会造成太大损害.

如果在尝试仅分配少量内存时malloc恰好返回NULL,那么在尝试从错误条件中恢复时必须谨慎,因为任何后续操作malloc都会失败,直到有足够的内存可用.

默认的C++运算符new通常是使用的相同分配机制的包装器malloc().

  • 引用一个关于如何破坏Linux默认值**的良好咆哮的+1.一个好的程序应该总是检查`malloc`的返回值.如果用户错误配置了他们的系统(或者将其保留在破坏的默认配置中),那么当然这可能没有帮助,但是你无能为力,崩溃超出了你的责任范围.但是如果你没有检查`malloc`的返回值,你的程序将在用户/管理员**实际关心正确性**并禁用过度使用的系统上运行时收支平衡.然后,用户可能会考虑您的程序废话.:-) (8认同)
  • 嗯,事实比这复杂一点.进程地址空间有漏洞; 例如,程序可能永远不会触摸BSS中的所有页面,或者更改在数据段中映射的页面.对于桌面/服务器系统来说,低估通常是一个比过度使用更大的问题.如果启用了交换分区,那么在事情变得非常糟糕之前也会提供一些缓冲. (2认同)

Fre*_*Foo 5

在Linux上,如果由于内核的过度分配策略而没有足够的内存,你确实不能依赖malloc返回NULL,但你仍然应该检查它,因为在某些情况下malloc 返回NULL,例如当你要求的内存超过机器中可用的内存时总共.Linux malloc(3)联机帮助页将调用称为"一个非常糟糕的错误",并包含有关如何关闭它的建议.

我从未听说过其他Unix变种中也会出现这种情况.

至于"寻呼痉挛",这取决于机器设置.例如,我倾向于不在笔记本电脑的Linux安装上设置交换分区,因为你担心的确切行为可能会杀死硬盘.我仍然喜欢我运行的C/C++程序来检查malloc返回值,给出适当的错误消息,并在可能的情况下自行清理.