-1

有时诸如库错误之类的事情将不允许我的程序继续运行,例如调用SDL_Init变坏。我应该尝试释放尽可能多的内存,还是直接退出?我还没有看到任何人们不只是退出的小例子,但我不够聪明,无法阅读 DOOM-3 代码或类似的任何东西。

4

3 回答 3

2

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

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

当然,如果“库错误”是指:

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

或者,没有库:

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;
}

在这里,我试图创建一个字符串数组,但是当我用完内存时,我只会将一些字符串写入文件,释放它们占用的内存,然后继续。然后,我可以参考我写入必须从内存中清除的字符串的文件。在这种情况下,我可以确保,尽管它确实会导致一些额外的开销,但我的程序将运行良好。
但是,在第二种情况下,释放内存是必须的。我必须释放程序继续运行所需的内存,但考虑到所有因素,这很容易解决。

于 2013-11-08T12:12:04.477 回答
1

这取决于。这些天来,操作系统清理了你造成的混乱,但在嵌入式系统上你可能没有那么幸运。但即便如此,仍有一个问题,“那又怎样,我的系统还是坏了。我将重新启动/重新启动/再试一次”

就我个人而言,我喜欢以一种在退出时检查哪些资源正在使用并释放这些资源的方式来安排我的代码。无论是正常退出还是错误都没有关系。

于 2013-11-08T11:57:12.860 回答
0

释放尽可能多的内存并做其他必要的工作(等日志、备份),而不是直接退出。程序有责任释放它分配的内存。不依赖操作系统,以为程序结束后会释放内存。

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

于 2013-11-08T11:57:28.127 回答