如何避免在每次“返回”之前调用free()

时间:2013-04-12 12:43:55

标签: c free

我遇到了free()问题是malloc()。有没有办法避免在以下代码中多次写入free(p)?

char *p = (char*) (malloc(100 * sizeof(char)));
if (A)
{
    free(p);
    p=NULL;
    return -1;
}
a++;
if (B)
{
    free(p);
    p=NULL;
    return -1;
}
b++;
if (C)
{
    free(p);
    p=NULL;
    return -1;
}
free(p);
p=NULL;
return 0; 

6 个答案:

答案 0 :(得分:5)

这可能不受欢迎,但您可以在函数末尾使用单个goto标签进行清理

    char *p = malloc(100);
    int ret = -1;
    if (A)
        goto cleanup;
    a++;
    if (B)
        goto cleanup;
    b++;
    if (C)
        goto cleanup;
    ret = 0; /* success */
cleanup:
    free(p);
    return ret; 

请注意,我对您的代码进行了一些其他小的更改

  • malloc
  • 的回复中移除了演员表
  • 从您的分配计算中删除了sizeof(char)的使用。这保证是1
  • 在您的函数结束时删除了p的NULLing。它即将超出范围,因此它指向释放内存并不重要

答案 1 :(得分:2)

goto如何?在像资源回收这样的情况下,这并不是一件坏事,因为从干燥的角度来看,不重复代码实际上是好的。

// set res and then 
if (A) { goto cleanup;}
a++;
if (B) { goto cleanup;}
...
cleanup:
 free(p);
 p = NULL;
 return res;

答案 2 :(得分:2)

它总是取决于你想要提供什么证据......有大量的回报证明了早期出现并有时简化了阅读。但是,在某些情况下,它会强制复制大量代码。我个人更喜欢在方法中使用单个返回点并通过嵌套ifs创建逻辑。

读起来有点复杂,但你确定你不会忘记一个免费的......

int retCode = -1;

if (!A)
{
    a++;
    if (!B)
    {
        b++;
        if (!C)
        {
            retCode = 0;
        }
    }
}

free(p);
p=NULL;
return retCode;

答案 3 :(得分:1)

您可以使用goto。这是在C中为goto量身定制的典型用例之一。

if(condition) 
{ 
    goto cleanup;
}

cleanup:
    free(ptr);
    ptr = NULL;

答案 4 :(得分:0)

char *p = malloc(100);

// Step 1: evaluate the conditions
int aTrue = A ? 1 : 0;
int bTrue = B ? 1 : 0;
int cTrue = C ? 1 : 0;
free(p);
p = NULL;

// Step 2: evaluate the consequences
if (aTrue) return -1;
a++;
if (bTrue) return -1;
b++;
if (cTrue) return -1;

return 0;

答案 5 :(得分:0)

另一种选择:

char *p = (char*) (malloc(100 * sizeof(char)));

if (!A) {
    a++;
    if (!B)
        b++;
}

free(p);
p=NULL;

if (A || B || C)
    return -1;

return 0;