0

関数を呼び出した後、動的に割り当てられたメモリのポインターは何を指しますかfree()。ポインターは NULL を指していますか、それとも解放前に指していたのと同じ場所を指していますか。free() の実装には、これに関する何らかの標準があるか、プラットフォームごとに異なる方法で実装されていますか。

uint8_t * pointer = malloc(12);
printf("%p", pointer); // The current address the pointer points to
free (pointer);
printf("%p", pointer); // must it be NULL or the same value as before ?

編集: printf が同じ結果を生成することはわかっています。異なる実装でそれを当てにできるかどうかを知りたいだけです。

4

4 に答える 4

5

ポインター値は変更されません。ポインタ (メモリ アドレス)を値で に渡しますfree()free()関数は変数にアクセスできないため、変数pointerを に設定できませんNULL

2 つのprintf()呼び出しは、同一の出力を生成する必要があります。

于 2012-06-25T08:32:26.727 に答える
4

標準 (C99 の 6.2.4/2) によると:

ポインターの値は、それが指すオブジェクトがその寿命の終わりに達すると不確定になります。

実際には、私が知っているすべての実装は、サンプル コードに対して同じ値を 2 回出力します。ただし、メモリを解放すると、ポインター値自体がトラップ表現になり、ポインターの値を使用しようとすると (逆参照していなくても) 実装が何かおかしなことをすることは許容されます。

実装が異常なことをしたいと仮定すると、ハードウェアの例外またはプログラムの中止が最も妥当だと思います。ただし、ポインター値がレジスターにロードされるたびに、何らかの方法でアドレスが有効かどうかをチェックするように、多くの余分な作業を行う実装/ハードウェアを想像する必要があるでしょう。それは、メモリマップでそれをチェックすることによる可能性があります(この場合、割り当てを含むページ全体が解放され、マップされていない場合にのみ、私の仮想実装がトラップされると思います)、または他の手段です。

于 2012-06-25T08:40:46.400 に答える
1

free()メモリの割り当てを解除するだけです。ポインターはまだ古い場所 (ダングリング ポインター) を指しているため、手動で に設定する必要がありますNULL

ポインターを に設定することをNULLお勧めします。メモリの場所は他のオブジェクトに再利用される可能性があるため、自分のものではないデータにアクセスして変更できる場合があります。これは、クラッシュを生成しないか、関係のないある時点でクラッシュを生成しないため、デバッグが特に困難です。に設定するNULLと、存在しないオブジェクトにアクセスした場合に再現可能なクラッシュが保証されます。

于 2012-06-25T08:31:59.287 に答える