我应该在致命错误时释放分配的内存吗?

时间:2013-11-08 11:45:38

标签: c memory free fatal-error quit

有时像库错误之类的东西不允许我的程序继续进一步继续,就像调用SDL_Init一样糟糕。我应该尝试释放尽可能多的内存,还是只是退出?我还没有看到人们不会放弃的任何小例子,但我不够聪明,不能阅读DOOM-3代码或任何类似的东西。

3 个答案:

答案 0 :(得分:2)

我不会。如果程序崩溃,由于程序中发生了一些奇怪的,无法预料的事情,尝试释放任何分配的堆内存甚至可能毫无意义。
我认为如果可以的话,最好只调用exit (EXIT_FAILURE),并让操作系统尽可能好地回收你分配的内存。

但是,我会尝试清理您使用/声明/打开的任何其他资源,这些资源也可能导致泄漏。尽可能多地打开文件指针,或者清除周围的缓冲区 除此之外,我会说:把它留给操作系统。你的程序崩溃了,或者正在崩溃:在一个不可预见的情况下尝试清理自己可能毫无意义,或者 - 他们知道 - 最终弊大于利。

当然,如果通过“库错误”,您的意思是:

MYSQL *connection = mysql_init();
if (connection == NULL)
{//connection could not be initiated
    //what to do here?
}

或者,没有lib:

char **arr_of_strings = malloc(200*sizeof(char *));
//some code
arr_of_strings[0] = calloc(150, sizeof(char));
//some more
arr_of_strings[120] = calloc(350, sizeof(char));
if (arr_of_strings == NULL)
{//ran out of heap memory
    //what do I do here?
}

所以,基本上:这是一个问题:你的程序必须做什么,你能轻松找到解决你遇到的问题的方法。
例如,如果您正在编写一个mysql客户端,并且mysql_init调用失败,我认为很明显您无法继续。您可以尝试为可能发生这种情况的每个原因提供回退,或者您可以退出。我选择后者。
在第二种情况下,很明显你已经耗尽了堆内存。如果你打算将这些字符串写入文件,你可以像这样阻止这种错误:

int main()
{
    char **arr_str = malloc(20*sizeof(char *));
    const char *fileName = "output.txt";
    int i, j;
    int alloc_str(char ***str, int offset, int size);
    void write_to_file(const char *string, const char *fileName);
    for(i=0;i<10;++i)
    {
        if (alloc_str(&arr_str, i, 100+i) == -1)
        {
            if (i == 0) exit(EXIT_FAILURE);//this is a bigger problem
            for (j=0;i<i;++j)
            {//write what we have to file, and free the memory
                if (arr_str[j] != NULL)
                {
                    write_to_file(arr_str[j], fileName);
                    free(arr_str[j]);
                    arr_str[j] = NULL;
                }
                if (alloc_str(&arr_str, i, 100+i) != -1) break;//enough memory freed!
            }
        }
        //assign value to arr_str[i]
    }
    for(i=0;i<10;++i) free(arr_str[i]);
    free(arr_str);
    return 0;
}

void write_to_file(const char *string, const char *fileName)
{//woefully inefficient, but you get the idea
    FILE* outFile = fopen(fileName, "a");
    if (outFile == NULL) exit (EXIT_FAILURE);
    fprintf(outFile, "%s\n", string);
    fclose(outFile);
}

int alloc_str(char ***str, int offset, int size)
{
    (*str)[offset] = calloc(size, sizeof(char));
    if ((*str)[offset] == NULL) return -1;
    return 0;
}

在这里,我正在尝试创建一个字符串数组,但是当我内存不足时,我只会将一些字符串写入文件,释放它们占用的内存,然后继续。然后我可以回头查看我写的字符串文件,我必须从内存中清除它。在这种情况下,我可以确保,虽然它确实会带来一些额外的开销,但我的程序运行得很好 在第二种情况下,释放内存是必须的。我来释放我的程序继续运行所需的内存,但考虑到所有事情,它很容易修复。

答案 1 :(得分:1)

这取决于。现在,操作系统可以清理您所造成的混乱,但在嵌入式系统上,您可能不会那么幸运。但即使这样,也有一个问题,“那么,我的系统无论如何都要破坏。我只是重启/重启/再试一次”

就个人而言,我喜欢以退出时的方式安排我的代码,它会检查哪些资源正在使用并释放它们。它是正常退出还是错误并不重要。

答案 2 :(得分:0)

尽可能多地释放内存并执行其他必要的工作(例如,日志,备份),而不是仅仅退出。程序有责任释放它分配的内存。不要依赖操作系统,认为它会在程序结束后释放内存。

我不久就写了一个内存泄漏检测模块,它要求程序释放分配的内存。如果没有释放内存,则模块无法工作,无法判断内存块是否泄漏。