在C中处理错误和释放内存的正确方法

时间:2015-03-03 15:06:26

标签: c memory error-handling malloc

在某些函数中我需要用malloc()分配内存并且有几个if..else语句,比如伪代码说明:

allocate memory
if condition_1
    do_stuff
    if condition_2
        do_more_stuff
    else
        error
else
    error
free allocated memory
return

所以我在开始时分配内存,如果一切运行良好,它将被释放。但目前错误函数只打印错误消息并退出porgram。但是因为我经常阅读不释放内存,尽管当程序退出并且操作系统处理正常后处理释放时,它没有好的风格。我怎么能以懒惰的方式释放这笔钱?我是否必须编写一个错误函数,该函数将每个指针指向我已分配的必须释放的内存,指针可能是不同的数据类型?或者我应该在调用错误函数之前放置free(ptr)?一个错误函数,它接受一个数据类型为void且释放的指针数组,这样就可以了吗?

3 个答案:

答案 0 :(得分:3)

我有两个解决方案。

您可以在调用freeerror的位置添加标签:

void function(void)
{
    Memory *p = malloc(sizeof(*p));
    if (condition_1) {
        do_stuff();
        if (condition_2) {
            do_more_stuff();
        } else {
            goto err;
        }
    } else {
        goto err;
    }
    free(p);
    return;
err:
    free(p);
    error();
}

您还可以使用标记来标记错误:

void function(void)
{
    Memory *p = malloc(sizeof(*p));
    bool err = false;
    if (condition_1) {
        do_stuff();
        if (condition_2) {
            do_more_stuff();
        } else {
            err = true;
        }
    } else {
        err = true;
    }
    free(p);
    if (err)
        error();
}

我认为第二种解决方案在这种情况下看起来最好,但它们都同样有效。

答案 1 :(得分:1)

不要使用goto。使用一次。此外,如果您需要错误标志,请将其默认为true而不是false以保存代码:

...malloc...
err = 1;
do {
    ...
    if <condition> break;
    ...
    if <condition> break;
    ...
    if <condition> break;
    ...
    err = 0;
} while (0);
...free...
if (err) ...

答案 2 :(得分:0)

根据我的理解,当你因为错误退出程序而不想手动处理所有指针时,你关心释放所有内存。

这是一个有趣的想法,编写一个函数allocMemory,它返回malloc的结果,但也将指针放入链表,然后将freeMemory从列表中删除,最后释放迭代列表的所有函数并释放所有的指针。 使用allocMemory和freeMomory函数而不是malloc和free,并在出错时调用freeMemory函数。