成功して割り当てられた配列が大きすぎるときのポインターへのアクセスエラー

StackOverflow https://stackoverflow.com/questions/19846401

  •  29-07-2022
  •  | 
  •  

質問

私はこれに続いて非常に単純なコードを持っています、それは完全に機能します:

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;
}

理由はありますか?私はこれについて本当にあなたの助けに感謝します、ありがとう^^

役に立ちましたか?

解決

したがって、標準はスタックについては話していませんが、ほとんどの最新の実装は置かれます 自動変数 スタック上で、通常はスタックが間にあります 1M8M 配列サイズでオーバーフローします。さまざまなシステムの典型的なスタックサイズを見つけることができます ここ:

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

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

subq    $23952048, %rsp

ただし、副作用を介して追加する場合 std::cinstd::cout (ライブの例):

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

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

leaq    3(%rsp), %rbx

通常、aを生成します セグ障害 の上 Unixのようなシステム.

注意してください、あなたはこの警告にも気付くかもしれません:

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

それが理由です 可変長アレイ 標準ではありません C ++ (しかし、有効です C99) 範囲 GCC拡張機能 使用するとき -pedantic 拡張機能を使用しているときに警告します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top