【发布时间】:2012-02-21 11:09:09
【问题描述】:
假设我正在用 C 语言编写一个小库——比如说一些数据结构。无法分配内存怎么办?
这可能非常重要,例如我首先需要一些内存来初始化数据结构,或者我正在插入一个键值对并希望将其包装在一个小结构中。它也可能不太重要,例如像pretty_print 函数,它构建了一个很好的内容字符串表示。但是,它通常比您的平均错误更严重 - 可能根本没有继续的意义。大量在线使用malloc 的示例,如果它返回NULL,则直接退出程序。我猜很多真实的客户端代码也会这样做——只是弹出一些错误,或者将其写入stderr,然后中止。 (而且很多真实代码可能根本不会检查malloc 的返回值。)
有时返回NULL 是有意义的,但并非总是如此。错误代码(或只是一些布尔值 success 值),无论是作为返回值还是输出参数都可以正常工作,但似乎它们可能会使 API 混乱或损害 API 的可读性(再说一次,这可能在某种语言中有点像C?)。另一种选择是让调用者随后可以查询某种内部错误状态,例如使用get_error 函数,但是你必须小心线程安全,并且很容易错过;无论如何,人们往往对检查错误感到松懈,如果它完全是一个单独的函数,他们可能不知道,或者他们可能不会打扰(但我想这是他们的问题)。
(我有时会看到 malloc 包裹在一个函数中,该函数会再次尝试直到内存可用...
void *my_malloc(size_t size)
{
void *result = NULL;
while (result == NULL)
result = malloc(size);
return result;
}
但这似乎有点愚蠢,而且可能很危险。)
什么是处理这个问题的正确方法?
【问题讨论】:
-
优雅退出是我的选择。
-
@Till:这对于库代码来说是绝对不能接受的。
-
@R。哎呀,我在阅读这个问题时完全跳过了第一行。在这种情况下,返回 FALSE/NULL 并添加错误状态函数以获取详细信息。
-
在某些情况下,loop-until-memory-is-available 可能是一个合理的策略(尽管最好在循环中使用 sleep 来做到这一点,以便让其他东西可以释放记忆!)。这些情况通常是您控制系统上运行的所有内容并且您知道不会让所有应用程序死锁在同一个循环中等待彼此释放内存的情况。当然不是在独立的应用程序中。
标签: c malloc api-design