6

そうではないと確信していますが、おそらく黒魔術が含まれているので、私の質問は次のとおりです。

次のような構造体がある場合:

struct mystr {
    char * strp,
    unsigned int foo,
};

私はそれにメモリを割り当て、後で解放したいと考えています。しなければなりませんか

free(mystr_var->strp);
free(mystr_var);

それとも最後の行で十分free()ですか? 関数はポインターをたどって 2 つのポインターを解放しますか?

4

6 に答える 6

5

いいえ、 free はポインターに従いません。両方の行が必要です。

私は通常、次のような関数を書きます。

void freemystr(mystr *mystr_var)
{
    if (mystr_var)
    {
        free(mystr_var->strp);
        mystr_var->strp = NULL;
        free(mystr_var);
    }
}
于 2012-12-14T11:14:14.063 に答える
4

個別に割り当てられたすべてのメモリ ブロックは、個別に解放する必要があります。free()ポインタが指しているメモリブロックのみを解放し、そのメモリの内容はわかりません。

したがって、あなたの場合、最初に構造体に割り当てられた最も内側のメモリを解放し、最後に構造体ポインターを解放することで、正しい方法でそれを行っています。

構造体ポインタを単に解放すると、構造体メモリが解放されます。が保持char* strpするメモリは、プログラムの有効期間中にメモリ リークになります。

于 2012-12-14T11:19:29.900 に答える
3

いいえ、そうではありません。

これはまったく魔法ではなく、コンパイラにとっては単なる別の関数呼び出しです。

もちろん、何かvoid free(void *);を含むバイナリ データ ブロックが与えられてだまされることなく、ポインタに従う方法で実装する方法を自問してください。できません。

于 2012-12-14T11:14:09.920 に答える
2

いいえ。ポイントされているブロックを解放するだけです。

参照されたメモリを明示的に解放する必要があります。これを最初に行う必要があります (つまり、メモリを割り当てた方法とは逆の方向である可能性が最も高い)。

于 2012-12-14T11:14:11.883 に答える
2

いいえfree、すべてのメンバーに対して再帰的な解放を行うわけではありません。メモリを割り当てたすべてのメンバーを明示的に解放する必要があります。

構造体にメモリがどのように割り当てられ、どのように解放されるかを理解していれば、これは問題になりません。

struct mystr {
    char * strp,
    unsigned int foo,
};

malloc & friends を使用してメモリを割り当てた場合、メンバーにのみメモリが割り当てられます。あなたの場合、 one char*and one unsigned int. にデータを格納するためのメモリは割り当てられないことに注意してくださいchar*strpしたがって、データを保存する前に、メモリを再度割り当てる必要があります。文字列リテラルを直接割り当てる場合を除き、またはポインタstrpを使用して既存のメモリを指す場合を除きます。

例:

ケース 1:

struct mystr s;

s.strp = "literals"; // valid, no need to malloc

ケース 2:

char *p="abc";

s.strp = p; // valid, no need to malloc

strp他のすべての用途では、データを に格納する前にメモリを割り当てる必要がありますstrp

したがってfree、構造体変数を呼び出すと、 に割り当てられたポインタのみが解放strpされ、 が指すメモリは解放されませんstrp。それは単純に、がどこを指しているfreeかについての情報がないからです。strp

上記の 2 つの例では、strpデータを に格納するためのメモリを割り当てていないため、解放しないことに注意してくださいstrp。1人1人無料というシンプルなルールmalloc/calloc/realloc

于 2012-12-14T11:15:00.233 に答える
0

C99は、

free 関数は、ptr が指すスペースの割り当てを解除します。つまり、さらに割り当てられるようにします。ptr がヌル ポインターの場合、アクションは発生しません。それ以外の場合、引数が calloc、malloc、または realloc 関数によって以前に返されたポインターと一致しない場合、または空間が free または realloc の呼び出しによって解放された場合、動作は未定義です。

于 2012-12-14T11:20:07.947 に答える