4

前段时间我从网上下载了一个源码。有几个 malloc 调用,之后没有检查 NULL。据我所知,您需要在调用 malloc 后检查 NULL。

有人在调用 malloc 后不检查 NULL 是否有充分的理由?我错过了什么吗?

4

4 回答 4

7

正如 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()返回错误时完成一些非常复杂的事情,那么您需要有相应的保护措施以确保您可以在内存非常低的情况下完成这些事情。通常,这意味着额外的复杂性,而且可能并不总是值得付出努力。

于 2012-04-14T23:02:48.803 回答
5

人们不检查是因为他们很懒惰,这使他们的代码更丑陋,而且他们不想弄清楚如何从各处的错误中恢复。

我听过一些程序员说,“如果我不能 malloc 一个块,那么系统很快就会崩溃,因为 VM 已满,那我为什么还要检查呢?”

我不同意。您应该检查错误,即使这意味着只记录错误并调用 exit() 或抛出异常。虽然我们倾向于使用具有巨大磁盘和永远在线的分页内存的系统,但行业已经发生了翻天覆地的变化,现在我们拥有内存有限且没有按需分页的智能手机和平板电脑。另外,即使在桌面上,我们的数据集也增长得如此之多,以至于有时 malloc 会失败。

如果您不想在任何地方添加额外的代码行,只需编写自己的 malloc 替换,调用 malloc 并检查错误并使用它来代替 malloc。

于 2012-04-14T22:32:17.450 回答
3

他们只是不关心意外的崩溃!

当你做 malloc 时,你很可能会立即存储一些东西。因此,如果您不检查 NULL,那么程序可能会在尝试在那里存储内容时崩溃。

这在小型程序中不太可能发生,因为当请求少量内存时 malloc 几乎不会失败。所以 malloc 不会返回 NULL。

但在我看来,即使在小程序中练习 for malloc 通常也很好NULL check

于 2012-04-14T22:13:26.303 回答
1

如果您需要更多内存malloc而不能给您更多内存,您能做些什么吗?
我想优雅地退出。
但是如果你退出,我猜他们认为你如何退出并不重要(还不如崩溃和避免,他们认为检查 null 的“开销”)。
也许功能是他们不需要清理代码?
不过我不同意。你应该检查NULLmalloc 的回报

于 2012-04-14T22:15:09.303 回答