なぜアドレス 0 がヌル ポインタに使用されるのですか? 質問する

なぜアドレス 0 がヌル ポインタに使用されるのですか? 質問する

C (または C++) では、ポインターの値が 0 の場合、ポインターは特別です。メモリを解放した後はポインターを 0 に設定するようにアドバイスされています。これは、ポインターを再度解放しても危険ではないことを意味するためです。malloc を呼び出すと、メモリを取得できない場合は値 0 のポインターが返されます。if (p != 0)渡されたポインターが有効であることを確認するために、常に を使用します。

しかし、メモリのアドレス指定は 0 から始まるので、0 は他のアドレスと同様に有効なアドレスではないのでしょうか? その場合、0 はどのようにして null ポインターの処理に使用できるのでしょうか? 代わりに負の数が null にならないのはなぜでしょうか?


編集:

たくさんの良い回答があります。回答で述べられていることを私自身の解釈で要約し、誤解があればコミュニティが訂正してくれることを願っています。

  • プログラミングの他のすべてと同様に、これは抽象化です。単なる定数であり、アドレス 0 とは実際には関係ありません。C++0x では、キーワードを追加することでこれを強調していますnullptr

  • これはアドレスの抽象化ではなく、C 標準で指定された定数であり、コンパイラは、それが「実際の」アドレスと等しくならないようにし、0 がプラットフォームで使用する最適な値でない場合は他の null ポインターと等しくする限り、それを他の数値に変換できます。

  • 初期の頃のように抽象化されていない場合は、アドレス 0 はシステムによって使用され、プログラマーにはアクセスできません。

  • 私の負の数の提案は、少し乱暴なブレインストーミングだったことを認めます。アドレスに符号付き整数を使用すると、ヌル ポインタ (-1 など) を除いて、有効なアドレスを作成する正の整数と無駄になる負の数の間で値空間が均等に分割されることになるので、少し無駄があります。

  • 任意の数値が常にデータ型で表現できる場合、それは 0 です。(おそらく 1 もそうです。符号なしの場合は 0 または 1 になる 1 ビット整数、符号付きの場合は符号付きビットのみ、または [-2, 1] になる 2 ビット整数を考えています。ただし、0 を null にし、1 をメモリ内のアクセス可能な唯一のバイトにすることもできます。)

まだ私の心の中で解決されていないことがあります。Stack Overflowの質問特定の固定アドレスへのポインタヌルポインタの0は抽象化されているとしても、他のポインタ値は必ずしもそうではないということが分かります。これは、私がStack Overflowで別の質問を投稿するきっかけとなりました。アドレス 0 にアクセスしたい場合はありますか?

ベストアンサー1

2点:

  • ソースコード内の定数 0 だけがヌルポインタです。コンパイラ実装は実行中のコードで必要な任意の値を使用できます。一部のプラットフォームでは、実装がヌルポインタとして使用する可能性のある「無効な」特別なポインタ値があります。C FAQ には、次のような質問があります。「真面目な話、実際のマシンで、ゼロ以外のヌル ポインター、または異なる型へのポインターの異なる表現が実際に使用されたことがあるでしょうか?」は、実行時に異なる表現で表現されるものの、C ソースでは 0 がヌル ポインターであるというこの特性を使用するプラットフォームがいくつかあることを指摘しています。C++ 標準には、「値が 0 の整数定数式を変換すると常にヌル ポインターが生成されますが、値が 0 になるその他の式を変換すると必ずしもヌル ポインターが生成されるわけではありません」と明記した注記があります。

  • 負の値は、アドレスと同様にプラットフォームで使用できる可能性があります。C 標準では、ヌル ポインターを示すために使用するものを選択する必要があり、ゼロが選択されました。正直なところ、他のセンチネル値が考慮されたかどうかはわかりません。

ヌル ポインターの唯一の要件は次のとおりです。

  • 実際のオブジェクトへのポインタと比較すると等しくないことが保証されている
  • 2 つの null ポインタは等しいとみなされます (C++ では、同じ型へのポインタに対してのみこれが当てはまるように改良されています)

おすすめ記事