我可以依靠malloc返回NULL吗?

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

在相关说明中,Herb Sutter说,处理C ++内存错误是徒劳的,因为在实际发生异常之前系统会长期处于分页痉挛状态。 这也适用于malloc吗?


引用Linux手册:

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

# echo 2 > /proc/sys/vm/overcommit_memory

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

如果malloc在尝试仅分配少量内存时发生返回NULL ,那么在尝试从错误条件中恢复时必须谨慎,因为随后的malloc可能会失败,直到有足够的内存可用。

默认的C ++操作符new通常是malloc()使用的相同分配机制的包装。


在Linux上,如果由于内核的重定位策略而导致内存不足,您确实可以不依赖malloc返回NULL ,但是您仍然应该检查它,因为在某些情况下, malloc将返回NULL ,例如,当您询问内存比在机器中总共可用。 Linux malloc(3)联机帮助页调用了“非常糟糕的错误”,并包含关于如何关闭该错误的建议。

我从来没有听说过其他Unix变体中也会发生这种行为。

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


检查malloc的返回对你自己来说并没有多大帮助,使你的分配更安全或者更不容易出错。 如果这是您实施的唯一测试,它甚至可能成为陷阱。

当使用0的参数调用时,标准允许malloc返回一个唯一的地址,不是一个空指针,然而你无权访问它。 因此,如果您只测试返回值是否为0但不测试malloccallocrealloc的参数,则可能会稍后再遇到段错误。

这种错误情况(内存耗尽)在“托管”环境中非常罕见。 通常,在你遇到这种错误之前,你早已陷入困境。 (但是,如果你正在编写运行时库,是一个内核黑客或火箭建造者,这是不同的,并且测试非常有意义。)

然后,人们倾向于用复杂的错误条件捕获代码来修饰代码,这些错误条件包含多行代码,执行perror和类似代码,这可能会影响代码的可读性。

我认为这个“检查malloc的回报”被高估了很多,有时甚至是很顽固地辩护。 其他事情更重要:

  • 总是初始化变量。 对于指针变量来说这是至关重要的,让程序在事情变得糟糕之前很好地崩溃。 struct s中未初始化的指针成员是很难找到的错误的重要原因。
  • 总是检查malloc和Co.的参数,如果这是一个像sizof toto这样的编译时常sizof toto那么不会有问题,但始终确保向量分配正确处理零个案。
  • 检查malloc返回的一个简单的事情就是用memset(malloc(n), 0, 1)来包装它。 这只是在第一个字节中写入0 ,并且如果malloc发生错误或n0开头,则会崩溃。

    链接地址: http://www.djcxy.com/p/78493.html

    上一篇: Can I rely on malloc returning NULL?

    下一篇: Behaviour of malloc with delete in C++