2

次のことを考慮してください。

int * i = malloc(sizeof(int));
free(i);

私は現在、i割り当て解除されたメモリを指しているシナリオにいますが、それもゼロではありません。これは C プログラミングの一般的なエラーiです。次のようなことを行う前に、それがまだ有効なポインターであることを確認する方法はありますか。

*i++; //probable EXC_BAD_ACCESS crash

メモリを再利用しない限り、100% 信頼できる (誤検知のない) メソッドが存在することは完全に不可能であることはわかっています。しかし、ほとんどの場合に機能するものは、デバッグに最適です。

編集

ポインターを NULL に設定するべきではないと主張しているわけではありません。壊滅的な影響を与えずにアドレスを突くための移植可能な (POSIX っぽい) 方法があるかどうか疑問に思っているだけです。時間から発生する複雑なマルチスレッドの問題をデバッグすることに興味があるだけです。時間に。

4

5 に答える 5

2

valgrind の memcheck ツールを使用して、デバッグに役立つものを取得します。アクセスが発生すると、無効な読み取りまたは無効な書き込みエラーが表示されます。

@Anthalesは正しいです。解放したらすぐにポインターをNULLに設定する必要があります。ポインターへの参照が複数ある場合、これはさらに複雑になります。あなたの状況の詳細を知らなければ、これを行う方法を正確に言うことはできませんが、可能な解決策は、さまざまな構造体に、特定のポインタではなくそのメモリへの参照を要求できるようにすることです。

于 2012-04-18T22:19:37.093 に答える
2

いいえ。

静的分析とライブ ツール (valgrind や Guard malloc など) は、この問題の解決に役立ちます。プログラムの作成方法を変更すると、所有権と有効期間をより簡単に理解するのにも役立ちます。

この機能をもっと詳しく知りたい場合は、カスタム アロケータを使用できますが、非常に役立つツールが存在します。

于 2012-04-18T22:29:29.877 に答える
1

非 NULL ポインター値が有効かどうかをポインター値自体から知る (移植可能な) 方法はありません。同様に、ポインターが自動、静的、または動的エクステントのオブジェクトを指しているかどうかを知る (移植可能な) 方法はありません。プラットフォームのメモリ モデルに精通している場合は、ある程度の推測ができるかもしれませんが (つまり、0x00000001 は有効なメモリ位置ではない可能性があります)、それだけです。

そのすべての情報をポインター自体とは別に追跡するか、ポインターの使用方法に何らかの規律を課す必要があります。

于 2012-04-18T22:28:53.703 に答える
0

C で実際にできることは、iまだ何かを指しているかどうかを知るのに十分な情報を渡すことだけです。

哲学的には、安全にインクリメントできるものをまだ指し示している*i++;かどうかがわからない場合、そうであってもそれをインクリメントするのが正しいことをどのように知ることができますか?i

これは、C での配列の使用と同様の状況です。データへのポインターとそれに付随するサイズ インジケーターの両方を渡す習慣が身に付きます。または、両方を構造体にラップします。

がどのように使用されているかのより大きな例を示すことができればi、人々は必要な追加情報を参照点に追加する慣用的な方法を推奨することができます。

于 2012-04-18T22:22:00.490 に答える
0

解放されたポインターを のNULL直後に設定するのが好きな人もいますfree:

#define paranoid_free(ptr)    (free(ptr), (ptr) = NULL)

free(NULL)これには、 C で定義されている (無操作として)二重解放の問題を回避するという利点があります。ただし、ポインターを逆参照して、プログラムの他の場所で未定義の動作を呼び出すことを防ぐことはできません。

于 2012-04-18T22:33:42.690 に答える