2011-10-23 14 views

答えて

2

お使いのオペレーティングシステムでは、プログラムに属していないメモリロケーションにアクセスすることはできません。しかし、カーネルモードでも動作します...

+0

私は、各プロセスが独自の仮想アドレス空間を持っていると思いました。だから、0x0から始めて、すべてのスペースは私のプロセスであり、私はそれにアクセスできるはずですか? – AnkurVj

+1

@AnkurVj:すべての仮想空間はあなたのものですが、それでも有効な場所になるように割り当てる必要があります。 –

+0

整数を宣言し、そのアドレスを出力するとします。その場所は実際の物理メモリの場所ですか? – AnkurVj

1

メモリの場所ではなく、1を印刷しようとしています。 1は有効なメモリ位置ではありません。実際のメモリ位置を印刷するには:

printf("%p", p); 

icktoofayが指摘されているので、%pに注意してください。

+0

私は、ポインタの正しい書式指定が '%d'ではなく'%p'であると信じています。 – icktoofay

+0

うん、あなたもそれを行うことができます。 –

+0

いいえ。メモリの場所を印刷しようとしていません。私は実際にそのメモリ位置に格納されているものを印刷しようとしています – AnkurVj

4

あなたのポインタは有効なものを指していません。あなたがするのは、ポインタへのポインタに値1を代入することですが、1は有効なメモリ位置ではありません。

ポインタ値を取得する唯一の有効な方法は、アドレスの変数を取るか、または割り当て関数を呼び出すのいずれかです:限り:「なぜ問題がなければならない」については

int a; 
int * p1 = &a; // OK 
int * p2 = malloc(sizeof(int)); // also OK 

*p1 = 2; 
*p2 = 3; 

あなたが無効なポインタを逆参照すると、定義されていない振る舞いが起こるので、何かが起こる可能性があります。これは、任意の制限を導入したくない場合に言語を指定する唯一の賢明な方法です。実装が容易です。

現実的には、現代のオペレーティングシステムでは通常、賢明な仮想メモリマネージャがあり、必要に応じてメモリを要求する必要があります。アドレス1のメモリがコミット済みのページにない場合は、 OSから。実際のアドレスの近くでポインタ値を入力しようとすると、エラーが発生しない可能性があります(おそらくページ境界を越えるまで)。

2

いいえ、アドレス1はプログラムのアドレス空間にありません。自分が所有していないセグメントにアクセスしようとしていて、セグメンテーション違反を受け取りました。

3

これに正しく答えるには、実際にはいくつかの要因が必要です。しかし、アドレス0x00000001(ページ0)はマッピングされておらず、また保護されていない可能性が高い。

通常、ページ0の範囲内のアドレスは、何らかの理由でユーザーアプリケーションから禁止されています。 (プロセッサに応じて)カーネル空間であっても、ページ0のアドレスは保護されることが多く、ページがマップされ、アクセスが有効になっている必要があります。

編集: もう1つの理由は、整数アクセスが整列していないことが原因でsegfaultingする可能性があるということです。

+0

+1は、セキュアなオペレーティングシステムではマッピングページ0が許可されていないことに言及しています(カーネルに対する攻撃につながる可能性があります)。 –

関連する問題