次のコードがあります。
int *a = NULL;
int b;
b = *a;
何らかの形で未定義ですか?a が指す場所に読み取り専用でアクセスしようとしています。それは何をすることができますか?
何らかの形で未定義ですか?
はい、動作は未定義です。
a が指す場所に読み取り専用でアクセスしようとしています。
指摘された場所は存在しません。そこには何もありません。何かを読み取るには、読み取る値が必要ですが、null ポインターがポイントしている...どこにもありません。それは何も指していません。
実装は、nullポインターの物理値を選択して、特定のプラットフォームで値を何も含まないアドレスを「指す」ようにします。つまり、そこには何も見えないということです。さらに、最新の仮想メモリプラットフォームでは、そのアドレスに関連付けられた特定の「そこ」さえない場合があります。
純粋な好奇心からそれを行っている場合でも、典型的な最新のプラットフォームでは機能しません。その[仮想]メモリ領域は通常「あなたのものではない」ため、ハードウェア/ OS保護メカニズムによって(プログラムのクラッシュ)。
一方、言語では、nullポインターを逆参照しようとすると、逆参照の目的に関係なく、未定義の動作が発生することが示されています。
はい、それは完全に未定義の動作です。null ポインターを逆参照しています。なんでも起こる可能性がある。
NULL ポインターを逆参照しないでください。小川を渡るようなものですが、さらに悪いことです。あなたが何を達成しようとしているのかさえわかりませんか?2 つのポインターを NULL に初期化しようとしていますか?
結果は未定義であり、プラットフォームによって異なります。
NULL は 0 に等しいです。したがってint* a = NULL
、アドレス 0 へのポインターを作成することを意味します。これには整数が含まれている必要があります。
by を逆参照するb = *a
ことで、アドレス 0 に移動してデータを取得するようにプログラムに指示します。
プラットフォームによっては、ユーザー コードからアドレス 0 にアクセスできない可能性が高くなります。オペレーティング システム上で実行していない場合 (マイクロコントローラ環境など)、通常、アドレス 0 は内部 ROM の先頭です。それ以外の場合は、スタックの先頭などになる可能性があります。
ほとんどの場合、ヌル ポインターを逆参照すると、ヌル ポインター例外が発生します。
ここにポップアップする 2 つのアラームがあります。NULL
また、他のすべての形式の null ポインターは、標準によって厳密に禁止されています。多くの場合、そのようなポインターの表現のために all のビット パターンによって内部的に実現されるからで0
はなく、それがポインターがどこも指していないことを示すための 1 と 1 の予約値であるためです。これをしないでください。
整数値に対応するアドレスを指すポインターを持つこと0
は別のことです。そのような値と点の解釈は、たとえば何らかのトリックによってのみ強制できます。
union over {
int *a;
uintptr_t b;
} ov;
ov.b = 0;
int c = *ov.a;
次に何が起こるかは、プラットフォームに完全に依存します。0
がアドレス空間で有効なアドレスである場合、これは機能する可能性がありますが、おそらく機能しないでしょう。あなたがよく知らない限り、それをしないでください。