C 標準では、free
関数の動作が次のように定義されています。
free関数は、 ptrが指すスペースの割り当てを解除します。つまり、さらに割り当てられるようにします。
これは、後でmalloc
(または他の何かを) 呼び出すと、同じメモリ空間が再利用される可能性があることを意味します。
ポインタが に渡されるとすぐに、free()
それが指すオブジェクトはその寿命の終わりに達します。ポイント先のオブジェクトを参照しようとすると、未定義の動作が発生します (つまり、ポインターを逆参照することはできなくなります)。
それ以上に、ポインターの値自体がindeterminateになるため、ポインター値を参照しようとすると未定義の動作になります。参照: N1570 6.2.4p2:
オブジェクトがその有効期間外に参照された場合、動作は未定義です。ポインターの値は、それが指している (または直前の) オブジェクトがその存続期間の終わりに達すると、不確定になります。
のfree()
引数が (すべての C 関数の引数と同様に) 値で渡されることは事実であり、free
実際にはポインターを変更することはできません。これを考える 1 つの方法は、ポインターは呼び出しの前後で「同じ」値を持つが、その値は呼び出しの前は有効であり、呼び出しの後で不確定であるということです。
ポインター値を参照しようとしたり、逆参照しようとしても、「機能」しているように見える可能性があります。これは、未定義の動作の可能性のある多くの症状の 1 つです (エラーの検出と診断が難しくなるため、おそらく最悪の症状です)。