为什么有些人在调用malloc后不检查NULL?

5

不久前,我从互联网上下载了一份源代码。其中有几个malloc调用,在此之后没有检查是否为NULL。据我所知,在调用malloc后需要检查是否为NULL。

是否有人故意不检查malloc调用后的NULL?我有什么遗漏吗?


2
顺便说一下,这就是为什么异常优于错误代码的原因。 - GManNickG
2
因为在此之前有更加重要的事情需要考虑:https://gustedt.wordpress.com/2011/11/05/chasing-a-phantom-checking-the-return-of-malloc/ - Jens Gustedt
只有一个额外的信息:问题中提到的代码是由一位微软MVP创建的。 - Victor
4个回答

9
正如Jens Gustedt在评论中提到的,当malloc()返回错误时,您的程序很可能已经陷入麻烦了。当程序很可能无法正常工作时,是否有意义添加大量的错误处理代码来处理这种情况呢?对于许多程序来说,答案可能是“否”,但对于其他一些程序来说,做出适当的处理可能非常重要。
您可以尝试通过一个简单的“malloc-or-die”包装函数来分配内存,该函数保证分配成功或者程序将终止:
void* m_malloc(size_t size)
{

    void* p;

    // make sure a size request of `0` doesn't trigger
    // an error situation needlessly 
    if (size == 0) size = 1;

    p = malloc(size);

    if (!p) {
        // attempt to log the error or whatever
        abort();
    }

    return p;
}

一个问题是当你遇到内存分配失败时,你能够进行的可靠操作非常有限,也许仅仅是终止程序。即使是记录错误,也可能需要一些内存分配,因此记录日志的工具可能会有自己的问题(除非您的内存分配失败是由于尝试分配一个过大的内存块所致)。
为了解决这个问题,您可以尝试在程序早期分配一个“故障安全”块,这样当您需要记录错误时就可以释放它(我认为有很多程序使用这种策略)。但您愿意为这种错误处理付出多少努力取决于您具体的需求。如果您的程序需要确保在malloc()返回错误时完成某些复杂的任务,则需要相应的保护措施来确保您可以在非常低内存的情况下完成这些任务。通常这意味着额外的复杂性,而且可能并不总是值得去尝试。

6
人们不检查错误是因为他们懒惰,这会使得他们的代码更丑陋,而且他们不想弄清楚如何从各个方面进行错误恢复。
我听过一些程序员说:“如果我无法分配内存块,那么系统很快就会崩溃,因为虚拟内存已满,所以我为什么要费心检查呢?”
我不同意这种看法。即使只是记录错误并调用exit()或抛出异常,您也应该检查错误。尽管我们趋向于使用具有巨大磁盘和始终开启分页内存的系统,但现在行业已经倒转,我们有了内存有限且没有按需分页的智能手机和平板电脑。此外,即使在桌面上,我们的数据集也变得如此庞大,有时malloc也会失败。
如果您不想在每个位置添加额外的代码行,请编写自己的malloc替代品来调用malloc并检查错误,然后使用它来替换malloc。

3

他们根本不关心意外崩溃!

在使用malloc时,很有可能会立即存储一些内容。因此,如果您没有检查NULL,那么当尝试在那里存储某些内容时,程序可能随后崩溃。

在小程序中,请求少量内存时,malloc几乎不会失败,因此malloc不会返回NULL。

但是,在我看来,即使在小程序中,进行NULL检查也通常是个好习惯。


1
如果你需要更多的内存,而malloc无法提供更多,你能做些什么呢?
我猜就优雅地退出吧。
但是如果你退出了,我想他们认为你如何退出并不重要(最好崩溃并避免检查null的开销)。
也许这个功能没有任何清理代码的必要?
虽然我不同意。您应该在malloc的返回值上检查NULL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接