-1

私たちが知っているように、Linux の世界では、ユーザー空間の無限再帰 "main()" は "セグメンテーション違反" メッセージを受け取りますが、これは実際にはスタック オーバーフローが原因です。(ちょうど次のコードのように)

#include <stdio.h>
void main(void) 
{
    main ();
}

実験と質問:

コードを次のように変更します。

#include <stdio.h>
int cnt = 0; 
void main(void) {
    printf("cnt %d\n", cnt++);
    main();
}

テスト環境:

x86-64 Ubuntu、gcc-4.6

あなたの助けが必要です。事前に感謝します!

別の「cnt」値でセグメンテーション違反が発生する理由:

cnt: 523614

cnt: 523602

cnt: 523712

cnt: 523671

4

1 に答える 1

2

これはおそらくAddress space layout randomizationによるものです。プログラムのわずかに変更された例を実行すると、次のようになります。

#include <stdio.h>
int cnt = 0;
void main(void)
{
    int a;
    printf("cnt %d %p\n", cnt++, (void*)&a); fflush(stdout);
    main();
}

aのアドレスは、プログラムのさまざまな実行で一貫していないことがわかります。おそらく、スタックの初期サイズもわずかにランダム化されているため、このスペースに収まるスタック フレームの数がわずかに異なります。

PS: を追加したfflushので、プログラムの出力を安全にパイプ処理することができtailますgrep

P.S2: に変更printprintfて追加する必要がありまし#include <stdio.h>た。

P.S3: プログラムで最適化を使用しないでください。そうしないと、末尾呼び出しの最適化によって再帰が削除され、プログラムが実際に永久にループすることになります。私のバージョンのプログラムは、エイリアスのため、それを行いませんa

于 2013-06-24T08:32:07.320 に答える