C 在退出时释放所有堆
我的代码中充满了这样的片段:C 在退出时释放所有堆,c,memory,memory-management,heap-memory,C,Memory,Memory Management,Heap Memory,我的代码中充满了这样的片段: if (!(row = malloc(reading_size))) memory_error(); if (!(unknowns = calloc(terms, sizeof(*unknowns)))) { free(row); memory_error(); } // ... if (!(unknowns = realloc(unknowns, (terms += TERMS) * sizeof(*unknowns)))) { fre
if (!(row = malloc(reading_size))) memory_error();
if (!(unknowns = calloc(terms, sizeof(*unknowns)))) {
free(row);
memory_error();
}
// ...
if (!(unknowns = realloc(unknowns, (terms += TERMS) * sizeof(*unknowns)))) {
free(row);
free(unknowns);
memory_error();
}
它使代码变得相当混乱。现在,值得吗?如果内存分配失败,我真的不认为有必要释放一些其他变量
顺便说一下,函数memory\u error()
没有什么特别之处:
void memory_error(void) {
puts("Could not allocate memory.");
exit(EXIT_FAILURE);
}
或者,是否有一种解决方案可以在退出时释放所有堆?有人建议我做以下工作:
- 围绕
、malloc()
和calloc()
编写包装,在我的包装中处理它们的故障李>realloc()
- 以灵活的数据结构跟踪分配的内存
- 使用
注册一个函数,该函数将清除所有分配的内存(利用上述数据结构)atexit()
在这种情况下,最好的做法是什么?错误恢复有时最好使用
goto
语句处理
if (!(row = malloc(reading_size))) {
goto error_row;
}
if (!(unknowns = calloc(terms, sizeof(*unknowns)))) {
goto error_unknowns1;
}
// ...
if (!(unknowns = realloc(unknowns, (terms += TERMS) * sizeof(*unknowns)))) {
goto error_unknowns2;
}
error_unknowns2:
free(unknowns);
error_unknowns1:
free(row);
error_row:
memory_error();
goto
语句用于无法导致注销的情况下,仅注销在情况恶化之前已成功注册的设施。您可以自己创建一个:@Bathsheba我曾考虑过GC,但我认为这对我的项目来说是一个过度。这是一个命令行实用程序,所以可能不会发生内存泄漏,但我对最佳实践很感兴趣。就我个人而言,我只想让程序流程保持清晰和正确,就像您目前所做的那样。如果适当的话,可以考虑分配一个<代码>结构> <代码> s的数组。如果您在第一个内存分配错误上退出,则不必费心释放所有成功调用的内存。无论如何,这将由操作系统负责(如果你在一个有堆的平台上的话)。在退出时释放所有堆,给Lilyth镀金这不是一个坏主意,但你可能想解释一下为什么在这种情况下皱眉头的goto
是可以接受的。通常,在答案中使用goto
肯定会被否决。这是因为goto
很容易被误用。或者标签错误:最近的OpenSSL失败是由于使用了goto来误导标签(标签名为fail
,但实际上没有使功能失败,因为它只执行了清理)。但是在C中,它是C++析构函数的好替代品。<>代码> Goto >到处都是结构化编程概念不支持这种情况。这是错误处理中经常出现的情况。另一个允许goto
的点是嵌套循环的出口。