は私がセグメンテーション違反を得る は、なぜ私がセグメンテーションフォールトを得るのですか
int *p = 1;
printf("%d", *p);
次の手順を実行したとします。今、私が理解しているように、このメモリロケーション1は私のプログラムのアドレス空間にあります。なぜこのメモリ位置を読み取る際に問題があるはずですか?
は私がセグメンテーション違反を得る は、なぜ私がセグメンテーションフォールトを得るのですか
int *p = 1;
printf("%d", *p);
次の手順を実行したとします。今、私が理解しているように、このメモリロケーション1は私のプログラムのアドレス空間にあります。なぜこのメモリ位置を読み取る際に問題があるはずですか?
お使いのオペレーティングシステムでは、プログラムに属していないメモリロケーションにアクセスすることはできません。しかし、カーネルモードでも動作します...
あなたのポインタは有効なものを指していません。あなたがするのは、ポインタへのポインタに値1
を代入することですが、1
は有効なメモリ位置ではありません。
ポインタ値を取得する唯一の有効な方法は、アドレスの変数を取るか、または割り当て関数を呼び出すのいずれかです:限り:「なぜ問題がなければならない」については
int a;
int * p1 = &a; // OK
int * p2 = malloc(sizeof(int)); // also OK
*p1 = 2;
*p2 = 3;
あなたが無効なポインタを逆参照すると、定義されていない振る舞いが起こるので、何かが起こる可能性があります。これは、任意の制限を導入したくない場合に言語を指定する唯一の賢明な方法です。実装が容易です。
現実的には、現代のオペレーティングシステムでは通常、賢明な仮想メモリマネージャがあり、必要に応じてメモリを要求する必要があります。アドレス1
のメモリがコミット済みのページにない場合は、 OSから。実際のアドレスの近くでポインタ値を入力しようとすると、エラーが発生しない可能性があります(おそらくページ境界を越えるまで)。
いいえ、アドレス1はプログラムのアドレス空間にありません。自分が所有していないセグメントにアクセスしようとしていて、セグメンテーション違反を受け取りました。
これに正しく答えるには、実際にはいくつかの要因が必要です。しかし、アドレス0x00000001(ページ0)はマッピングされておらず、また保護されていない可能性が高い。
通常、ページ0の範囲内のアドレスは、何らかの理由でユーザーアプリケーションから禁止されています。 (プロセッサに応じて)カーネル空間であっても、ページ0のアドレスは保護されることが多く、ページがマップされ、アクセスが有効になっている必要があります。
編集: もう1つの理由は、整数アクセスが整列していないことが原因でsegfaultingする可能性があるということです。
+1は、セキュアなオペレーティングシステムではマッピングページ0が許可されていないことに言及しています(カーネルに対する攻撃につながる可能性があります)。 –
私は、各プロセスが独自の仮想アドレス空間を持っていると思いました。だから、0x0から始めて、すべてのスペースは私のプロセスであり、私はそれにアクセスできるはずですか? – AnkurVj
@AnkurVj:すべての仮想空間はあなたのものですが、それでも有効な場所になるように割り当てる必要があります。 –
整数を宣言し、そのアドレスを出力するとします。その場所は実際の物理メモリの場所ですか? – AnkurVj