free(str);
printf("%d\n", str->listeners);
printf への呼び出しは成功します (str のメンバーへの他の呼び出しと同様)。これはどのように可能ですか?
free(str);
printf("%d\n", str->listeners);
printf への呼び出しは成功します (str のメンバーへの他の呼び出しと同様)。これはどのように可能ですか?
例えるなら、あなたがアパートを借りていて (これがメモリーです)、賃貸契約を終了するが、鍵の複製 (ポインター) を保持していると想像してください。アパートが取り壊されていない場合、またはロックが変更されていない場合など、後でアパートに戻ることができる場合があります。しかし、それはかなり悪い考えであり、おそらくあなたはトラブルの山に巻き込まれるでしょう...
それは未定義の動作と呼ばれます。解放されたメモリを参照するポインターを逆参照しています。つまり、プログラムがクラッシュするなどとは想定できません。動作は未定義です。
あなたは運が悪いだけです。そのコードは未定義の動作を示します - メモリが解放されていないように見えることを含め、何かが起こる可能性があります.
メモリは解放されますが、積極的にクリアしても意味がないため、元の内容が残っている可能性があります。しかし、あなたはそれに頼ることはできません。
str
そうではなくNULL
、対応するメモリが他の割り当てによって上書きされていない限り、メモリの内容が変更されないため、引き続き機能free
します(ランタイムがメモリ領域を上書きしない場合free
)。しかし、これは明らかに未定義の動作であり、この方法で動作することに依存することはできません...
心に留めておくべきこと...
free()
メモリを返しません。理論上は可能であっても、実際に起こることはほとんどありません。これは、メモリは一般に 4kB のアラインされたページでのみ返すことができるためです。MMU がそのように機能するためです。MMU が見つかった場合、それをリッピングすると、上下のメモリを含むブロックが断片化され、全体が作成されます。逆効果のプロセス。(断片化は、動的メモリの効率的な使用の敵です。)