これはかなり基本的な質問かもしれません。null ポインターの値をゼロに設定する C 規則があることを理解しています。Windowsで新しい変数にスペースを割り当てることができ、その割り当てられたスペースのアドレスがたまたまゼロになる可能性はありますか? そうでない場合、そのアドレス領域は通常何が占有されていますか?
5 に答える
MS-DOS ではヌル ポインターはかなり有効なポインターであり、OS がリアル モードで実行されているため、実際には 0x0 アドレスをガベージで上書きし、カーネルを破損する可能性がありました。次のようなことができます。
int i;
unsigned char* ptr = (unsigned char *)0x0;
for(i = 0; i < 1024; i++)
ptr[i] = 0x0;
最新のオペレーティング システム (Linux、Windows など) は、物理メモリに直接アクセスできない保護モードで実行されます。
プロセッサーは、物理アドレスを、プログラムが使用する仮想アドレスにマップします。
また、アクセスしたものを追跡し、あえて自分のものではないものに触れると、問題が発生します(プログラムはsegfaultになります)。これには、0x0 アドレスの逆参照を試みることが含まれます。
のように「ポインタの値をゼロに設定する」場合
int *p = 0;
あなたが信じているように、必ずしも物理アドレス 0 を指すとは限りません。ポインターに定数のゼロ値が割り当てられる(またはそれで初期化される) 場合、コンパイラーはその状況を認識して特別な方法で処理する必要があります。コンパイラは、そのゼロを実装依存の null ポインター値に置き換える必要があります。後者は必ずしもゼロアドレスを指すとは限りません。
Null ポインター値は、他の目的に使用されない物理アドレスで表されることになっています。一部の実装で物理アドレス 0 が使用可能なアドレスである場合、そのような実装では、別の物理アドレスを使用してヌル ポインターを表す必要があります。たとえば、一部の実装では0xFFFFFFFF
、その目的でアドレスを使用する場合があります。そのような実装では、初期化
int *p = 0;
実際には、物理的なゼロではなく、物理p
的に初期化されます。0xFFFFFFFF
PS FAQ をご覧になることをお勧めします。
値0
に特別な意味はありません。ポインターを 0 に設定するのは規則であり、C コンパイラーはそれに応じて解釈する必要があります。ただし、物理アドレス 0 への接続はなく、実際にはそのアドレスは有効なアドレスである可能性があります。多くのシステムでは、下位アドレスには、割り込みベクトルなどのハードウェア関連のアドレスが含まれています。たとえば、Amiga では、アドレス 4 がオペレーティング システムへのエントリ ポイントであり、これも任意の決定です。
割り当てられたスペースのアドレスがゼロの場合、使用可能なメモリが不足しています。つまり、変数を割り当てることができませんでした。