2012-03-08 20 views
4
int a; 
printf("address is %u", &a); 

これはどちらですか?つまり、これはコンパイラによって生成されたアドレス、つまり仮想アドレスまたはローダーがRAMに物理アドレスを与えられたことを意味します。(&)のアドレスは、コンパイラによって生成されたアドレスまたはローダによって生成されたアドレスを与えますか?

毎回異なるアドレスを出力するので、RAMのアドレスである必要があります。ただ確実にしたい。

回答を参考にしたリンクを入力してください。

+1

ほとんどの場合仮想です。arduinoなどの実際のアドレス空間を持つシステムをプログラムしない限り – Anycorn

+0

これはWindows 7 PCまたは同様のコンピュータ用の場合は、それは仮想アドレスになります。しかし、いくつかのシステムでは、物理メモリアドレスになります。あなたが使用しているシステムを教えてくれるわけではないので、その質問に答えることは不可能です。 – Lundin

+0

これは仮想アドレスから物理アドレスへの変換が存在する場合の仮想アドレスです。そうでない場合は、物理的に(プログラムがインタプリタまたはVMで実行されている場合を除き、他の場合もあります)。このアドレスは、アプリケーションでローダーが選択する場所に基づいています。さまざまな理由により、この住所は異なる場合があります(例:セキュリティ上の理由または単に最後の場所がすでに他の場所に占められているなど)。 –

答えて

2

正しい答えは:「それは依存しています。」

(printf関数は、「%p」のディレクティブを使用する必要があり、かつ明確に定義されたネスのために「void *型」のアドレスをキャスト:

printf("%p\n", (void *)&a); 

間違いなく作品%Uを使用していないものの)あなたが使用しているフラグを使用している特定のコンパイラのために、あなたの特定のコンパイラのために使用することができます。)

@Alexが指摘しているように、変換が行われていれば、アドレスは仮想です(ほとんどの最新のOSや仮想マシンの "エミュレートされた物理" )。 "a"に静的な記憶期間があるが、実行時に(スタックに@Alsと書かれている)そうでなければ、アドレス自体は一般にリンク時またはロード時に決定される。 "static"または "extern"と宣言された変数は静的持続時間を持ちます。関数本体の外で宣言された変数は静的持続時間を持ちます。関数本体内で宣言された変数は、 "extern"または "static"のいずれも使用せず、自動保存期間を持ちます(通常POSIXスレッドを使用する場合と同様に複数のスタックが存在する可能性があります)。私が意味する

4

ユーザ空間のローカル変数に返されるアドレスは、常に物理アドレスではなく仮想アドレスです。

あなたのケースでは、変数aがローカルストレージ(スタック)に割り当てられ、プログラムにスタックスペースが割り当てられるたびに、変数はこのスタックフレーム内の特定のオフセットに配置されます。あなたのプログラムに割り当てられているスタックは、変数のために返されるアドレスも異なってくるたびに異なっている可能性があります。

+3

*常に仮想アドレス*コードがリアルモードで実行されているCPU上で実行されている場合はどうなりますか? CPUがx86であると仮定します。 –

+1

それでは毎回なぜ違うのですか?一度だけコンパイルすると、コードを実行するたびに同じアドレスが返されるはずです。 – Adorn

+1

いいえいいえいいえ...コンパイラによって生成されたアドレスは仮想アドレスで、 '&'演算子によって返されます。では、ローカルスタックはどこに入りますか?ローカルスタックアドレスが返された場合は、それは物理的なものです。 – Adorn

3

最新のOSであればすべて Cレベルで表示されるアドレスは仮想アドレスです。あなたが与える例は、スタック上の変数であり、実行ごとにthis'dが異なる理由は、(仮想)スタックアドレスがセキュリティ上の理由からランダム化されることです。

いずれにしても、ローダによって解決されたグローバルシンボルさえも、プロセスのアドレス空間に仮想アドレスがあります。

(これのすべては、組み込み機器用の真実ではないかもしれませんが、これは通常、Cを学習するときに、あなたが遭遇するものではありません)

+1

組み込みシステムに関しては、すべての賭けはオフであると言及しています。 – Dan

0

は、このコンパイラ生成されたアドレス、すなわち仮想アドレスまたは RAMの物理アドレス指定されたローダーです。

偽の二分法。コンパイラによって生成されたアドレスはリンカによって再配置され、&によって返されるのはこのアドレスです。 VMを使用しないNetWare 3のような奇妙なもので動作していない限り、仮想アドレスです。

関連する問題