在退出时释放所有堆

时间:2015-04-13 07:33:25

标签: 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)))) {
    free(row);
    free(unknowns);
    memory_error();
}

它使代码混乱了很多。现在,值得吗?如果内存分配失败,我真的不需要释放其他一些变量。

顺便说一句,函数memory_error()并不特别:

void memory_error(void) {
    puts("Could not allocate memory.");
    exit(EXIT_FAILURE);
}

或者,是否有解决方案在退出时释放所有堆?有人建议我做以下事情:

  • 围绕malloc()calloc()realloc()编写包装,以便在我的包装内处理它们的失败;
  • 跟踪灵活数据结构中分配的内存
  • 使用atexit()注册一个函数,该函数将清除所有已分配的内存(使用上述数据结构)。

我不太确定这一点,因为所有的释放都会在退出时完成,所以无论如何都是毫无意义的。据我了解,如果你不需要那个内存就可以释放内存。

这种情况下最好的行动方案是什么?

1 个答案:

答案 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语句用于在事情发生之前未能注册已成功注册的设施的情况。