2016-02-19 18 views
5

8メガバイトのスタックが各プロセスに与えられていると言われています。 このスタックはローカル変数の格納に使用されます。 スタックの最大サイズの配列を取る場合、それはオーバーフローする必要がありますか?巨大なローカル変数を持つスタックオーバーフロー?

int main() 
{ 
int arr[88388608]; 
int arr1[88388608]; 
int arr2[88388608]; 
while(1); 
return 0; 
} 

しかし、私は結果を得ることができません!

+2

スタックをオーバーフローさせたときに、*未定義の動作*が発生し、期待通りに動作しないように見えることがあります。また、最近のコンパイラはかなりスマートです。これらの配列は使用されていないので、なぜコンパイラが実際にそれらのためのスペースを作成する必要がありますか? –

+0

arの型を 'int'から' volatile int'に変更するとどうなりますか? –

+2

また、AFAIKはスタックのサイズがシステムによって異なる場合があります。 –

答えて

5

最適化コンパイラの世界へようこそ!

as-ifルールのため、コンパイラは、元のコードと同じ観察可能な結果を​​持つものを作成するだけで済みます。 ので、コンパイラが自由に場合:

  • は未使用のアレイ
  • が空ループ
  • スタックの主要外部から動的配列を格納削除 - 主にのみ呼び出さなければならない特殊な機能であるため一度環境

あなたは、スタックオーバーフローを観察したい場合(悪いものではなく、私たちの素敵なサイト:-))、 あなたべきによって:

  • 私はのように正確にすることができますように書いた何をすべきか、コンパイラを伝えるために
  • を外し、すべての最適化とpreferentlyデバッグモードでコンパイルの配列を埋めるためにいくつかのコードを使用し

次のコードは、とSIGSEGVを行います打ち鳴らす3.4.1 cc -g foo.c -o foo

#include <stdio.h> 

#define SIZE 88388608 

void fill(int *arr, size_t size, int val) { 
    for (size_t i=0; i<size; i++) { 
     arr[i] = val; 
    } 
}  
int main() { 
    int arr[SIZE]; 
    int arr1[SIZE]; 
    int arr2[SIZE]; 

    fill(arr, SIZE, 0); 
    fill(arr1, SIZE, 0); 
    fill(arr2, SIZE, 0); 
    printf("%d %d %d\n", arr[12], arr1[15], arr2[18]); 

    return 0; 
} 

としてコンパイルと-O2最適化レベルとしてコンパイルされた場合でも、このコードは正常に動作します...コンパイラは、今にしています私にとっては賢明で、実際に実行されるものを理解する唯一の真の方法であるアセンブリコードを徹底的に調べるのに十分な勇気はありません!

+0

@ Lingxi:あなたの答えはほぼ正しいです。あなたがC言語に翻訳してそれを元に戻す(そしてコメントで私にpingした)場合、私はそれをupvoteします。 –

関連する問題