7

malloc するこの構造体型があり、それを解放した後も、ポインターは割り当てたデータを指しています。これは、ポインターが空きメモリを指しているが、まだ再割り当てされていないためですか?

#include <stdio.h>

struct S {
    int value;
}

int main () {
    S *s = malloc(sizeof(struct S));
    s->value = 8910;
    free(s);
    printf("s: %i\n", s->value);
}
4

3 に答える 3

18

解放されたメモリはもうあなたのものではありません。しかし、それはそれが消えたり、何らかの形で変化したりすることを意味するものではありません. なぜあなたのプログラムは気にするのですか?時間の無駄です。おそらく、メモリを後続の で使用できるようにマークするだけで、それだけですmalloc()。またはそうではないかもしれません。自分のものではないメモリを使用すると、何かが起こる可能性があります。間違った値を返す、クラッシュする、正しい値を返す、フライト シミュレータ ゲームを実行するなどです。それはあなたのものではありません。それを台無しにしないでください。そうすれば、それが何をするかについて心配する必要はありません。

于 2013-09-02T23:41:39.960 に答える
4

C 標準では、free関数の動作が次のように定義されています。

free関数は、 ptrが指すスペースの割り当てを解除します。つまり、さらに割り当てられるようにします。

これは、後でmalloc(または他の何かを) 呼び出すと、同じメモリ空間が再利用される可能性があることを意味します。

ポインタが に渡されるとすぐに、free()それが指すオブジェクトはその寿命の終わりに達します。ポイント先のオブジェクトを参照しようとすると、未定義の動作が発生します (つまり、ポインターを逆参照することはできなくなります)。

それ以上に、ポインターの値自体がindeterminateになるため、ポインター値を参照しようとすると未定義の動作になります。参照: N1570 6.2.4p2:

オブジェクトがその有効期間外に参照された場合、動作は未定義です。ポインターの値は、それが指している (または直前の) オブジェクトがその存続期間の終わりに達すると、不確定になります。

free()引数が (すべての C 関数の引数と同様に) 値で渡されることは事実であり、free実際にはポインターを変更することはできません。これを考える 1 つの方法は、ポインターは呼び出しの前後で「同じ」値を持つが、その値は呼び出しの前は有効であり、呼び出しの後で不確定であるということです。

ポインター値を参照しようとしたり、逆参照しようとしても、「機能」しているように見える可能性があります。これは、未定義の動作の可能性のある多くの症状の 1 つです (エラーの検出と診断が難しくなるため、おそらく最悪の症状です)。

于 2013-09-02T23:53:56.807 に答える
2

free()言語の実装またはオペレーティング システムに対して、メモリが不要になったことを宣言するだけです。上書きされたときの動作は定義されていません。

于 2013-09-02T23:41:59.433 に答える