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 であることが保証されています
  • 関数の最後にあるNULLing を削除pしました。範囲外に出ようとしているので、解放されたメモリを指していても問題ありません
于 2013-04-12T12:46:37.580 に答える
2

ゴトウはいかがですか。このようなリソース再利用の場合、それは悪いことではなく、コードを繰り返さないため、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

それは常に、何を証拠に入れたいかによって異なります...多くのリターンがあると、証拠が早期に作成され、場合によっては読み取りが簡素化されます。ただし、場合によっては、大量のコードを複製する必要があります。個人的には、メソッド内に 1 つのリターン ポイントを持ち、ネストされた if を介してロジックを作成することを好みます。

読むのはもう少し複雑ですが、無料の...

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

使用できますgotogotoこれは、C で調整された典型的な使用例の 1 つです。

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 に答える