前段时间我从互联网上下载了一个源代码。有几次malloc调用,之后没有检查NULL。据我所知,您需要在调用malloc后检查NULL。
是否有充分的理由让某人在调用 malloc 后不检查 NULL?我错过了什么吗?
正如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()
则需要具有相应的保护措施,以确保您可以在内存非常低的情况下执行这些操作。 通常,这意味着额外的复杂性,并且可能并不总是值得付出努力。
人们不检查是因为他们懒惰,这使他们的代码更丑陋,他们不想弄清楚如何从各地的错误中恢复。
我听过一些程序员说,"如果我不能恶意处理一个块,系统很快就会崩溃,因为虚拟机已满,所以我为什么要费心检查呢?
我不同意。您应该检查错误,即使这意味着只是记录错误并调用 exit() 或抛出异常。虽然我们倾向于具有巨大磁盘和始终在线分页内存的系统,但行业已经翻转,现在我们拥有 RAM 有限且没有按需分页的智能手机和平板电脑。此外,即使在桌面上,我们的数据集也增长得如此之快,以至于有时 malloc 会失败。
如果您不想在任何地方添加额外的代码行,只需编写自己的 malloc 替换来调用 malloc 并检查错误并使用它而不是 malloc。
他们只是不在乎意外的崩溃!
当你做malloc时,你很可能会立即存储一些东西。因此,如果您不检查 NULL,则程序在尝试在那里存储某些内容时可能会随后崩溃。
这在小程序中不太可能,因为当请求少量内存时,malloc 几乎不会失败。所以 malloc 不会返回 NULL。
但在我看来,即使在小程序中练习 malloc 的NULL check
通常也是件好事。
如果你需要更多的内存,malloc
不能给你更多,你能做些什么吗?
我想优雅地退出。
但是如果你退出,我猜他们认为你如何退出并不重要(不妨崩溃并避免,他们认为检查空的"开销")。
也许功能是这样的,他们不需要清理代码?
不过我不同意。您应该检查 malloc 退货NULL