1

我面临一个 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; 
4

6 回答 6

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 。它即将超出范围,因此它指向已释放的内存并不重要
于 2013-04-12T12:46:37.580 回答
2

goto怎么样。在这种资源回收的情况下,这样做并不是一件坏事,并且由于不重复代码,从 DRY 的角度来看实际上是件好事。

// set res and then 
if (A) { goto cleanup;}
a++;
if (B) { goto cleanup;}
...
cleanup:
 free(p);
 p = NULL;
 return res;
于 2013-04-12T12:46:47.267 回答
2

它总是取决于你想证明什么……有很多回报可以证明早点出来,有时还可以简化阅读。但是,在某些情况下,它会强制复制大量代码。我个人更喜欢在方法中有一个返回点,并通过嵌套的 ifs 进行逻辑。

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

int retCode = -1;

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

free(p);
p=NULL;
return retCode;
于 2013-04-12T12:47:22.050 回答
1

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

if(condition) 
{ 
    goto cleanup;
}

cleanup:
    free(ptr);
    ptr = NULL;
于 2013-04-12T12:46:50.060 回答
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;
于 2013-04-12T12:51:08.773 回答
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; 
于 2013-04-12T12:54:41.137 回答