プログラムメモリ割り当て
#include<stdio.h>
int a=10;
void main()
{
int i=0;
printf("global = %p, local = %p\n",&a,&i);
main();
}
出力
[email protected]:~/Advanced_Unix/Chapter7$ ./a.out
global = 0x804a014, local = 0xbfff983c
global = 0x804a014, local = 0xbfff980c
.
.
.
global = 0x804a014, local = 0xbf7fac9c
global = 0x804a014, local = 0xbf7fac6c
global = 0x804a014, local = 0xbf7fac3c
Segmentation fault (core dumped)
[email protected]:~/Advanced_Unix/Chapter7$
上記のプログラムは、セグメンテーションフォールトエラーを取得します。なぜなら、メインは再帰的に自身を呼び出すからです。以下は、Cプログラムへのメモリ割り当て の割り当てです。
メモリ割り当て
__________________ __________________
| | | |
| stack | | Main |
| ↓ | |----------------|
------------------ | Main |
| | |----------------|
| <Un Allocated| | Main |
| space> | |----------------|
------------------ | Main |
| | |----------------|
| ↑ | | Main |
| Heap | |----------------|
| | | Main |
| | |----------------|
__________________ |////////////////| ---> Collision occurs. So, Segmentation fault Occurs.
| | |________________|
| data | | data |
__________________ |________________|
| text | | text |
__________________ |________________|
Figure(a) Figure(b)
だから、私は再帰的に、図(B)のように示されているメイン呼び出しを期待します。データセグメントに到達すると、衝突が発生します。 これが発生した場合、main関数に割り当てられるスペースがなくなります。したがって、セグメント化エラーが発生します。上記のプログラムを使って実験します。 そのプログラムでは、グローバル変数 'a'のアドレスは「0x804a014」です。 mainが呼び出されるたびに、ローカル変数 "i"が宣言されます。だから、私は セグメンテーションフォールトの前に、私のアドレスはほぼ 'a'のアドレスになると期待しています。しかし、両方のアドレスは非常に異なっています。ここで何が起こっているのですか?
セグメンテーションフォールトエラー時に 'a'と 'i'のアドレスが同じ範囲にないのはなぜですか。だから、 メインがスタックサイズに達してオーバーフローするかどうかをどうやってチェックするか?
プログラムを一時停止し、 '/ proc/pid/maps'を見てください。そこにはライブラリのようなものがあります。加えて、スタックサイズ(ulimit)に実際の制限があります – Petesh
ライブラリのオブジェクトのアドレスを1つ印刷できますか?言って、&stdin?または標準ですか? –
@Peteshこれはスタックサイズです:bf99c000-bfa39000 rw-p 00000000 00:00 0 [スタック] – mrg