我的代码很像这些代码片段:
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_error()
并不特别:
void memory_error(void) {
puts("Could not allocate memory.");
exit(EXIT_FAILURE);
}
或者,是否有解决方案在退出时释放所有堆?有人建议我做以下事情:
malloc()
,calloc()
和realloc()
编写包装,以便在我的包装内处理它们的失败; atexit()
注册一个函数,该函数将清除所有已分配的内存(使用上述数据结构)。我不太确定这一点,因为所有的释放都会在退出时完成,所以无论如何都是毫无意义的。据我了解,如果你不需要那个内存就可以释放内存。
这种情况下最好的行动方案是什么?
答案 0 :(得分:2)
错误恢复有时最好用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
语句用于在事情发生之前未能注册已成功注册的设施的情况。