1

次の非常に単純なコードがあり、完全に機能します。

void func(int *tab)
{
    return;
}

int main()
{
    int maxsize = 999*999;
    int tabs[maxsize][6];

    return 0;
}

ただし、これを取得するようにメインを変更すると、クラッシュします。

int main()
{
    int maxsize = 999*999;
    int tabs[maxsize][6];

    func(tabs[0]);

    return 0;
}

理由はわかりますか?この度は本当にお世話になりました、ありがとうございます(^^)

4

1 に答える 1

2

そのため、標準ではスタックについては言及されていませんが、最新の実装のほとんどは自動変数をスタックに配置し、スタックは通常 と の間1M8M配列サイズでオーバーフローします。異なるシステムの一般的なスタック サイズは、次の場所で確認できます

SunOS/Solaris   8172K bytes
Linux           8172K bytes
Windows         1024K bytes
cygwin          2048K bytes

最初のエラーがセグメンテーション フォールトにならない理由は、コンパイラが実際にメモリを参照する必要がないためですが、何らかの副作用を引き起こす必要がある場合、コンパイラは実際にスタック オーバーフローを引き起こすメモリ アクセスを生成します。gcc副作用なしでこのコードを実行すると使用していると言ったので(ライブの例)、スタックポインターは実際に調整されますが、使用されることはありません。

subq    $23952048, %rsp

しかし、 and を介して副作用を追加するstd::cinstd::cout( live example ):

std::cin >> tabs[maxsize-1][5] ;
std::cout << tabs[maxsize-1][5] << std::endl ;

次に、スタック ポインターを使用する必要があります。

leaq    3(%rsp), %rbx

通常、Unix系のシステムではセグ フォールトが発生します。

次の警告にも注意してください。

warning: ISO C++ forbids variable length array ‘tabs’ [-Wvla]

これは、可変長配列が標準のC++ではないため (ただしC99 では有効です)、gcc 拡張機能であり、使用すると拡張機能を使用し-pedanticているときに警告が表示されます。

于 2013-11-07T21:00:55.393 に答える