1

重複の可能性:
大きな配列を宣言するときにスタック オーバーフロー例外を取得する

私のシステムはx86-64 linux、ここに私の簡単なコードです:

#include<stdio.h>
#define N 1024
int main()
{
    int a[N][N];
    int b[N][N];
    printf("hello world\n");
    return 0;
}

そして、objdump からのそのアセンブリ コード:

00000000004004fc <main>:

4004fc: 55                      push   %rbp
4004fd: 48 89 e5                mov    %rsp,%rbp
400500: 48 81 ec 00 00 80 00    sub    $0x800000,%rsp
400507: bf c4 05 40 00          mov    $0x4005c4,%edi
40050c: e8 cf fe ff ff          callq  4003e0 <puts@plt>
400511: b8 00 00 00 00          mov    $0x0,%eax
400516: c9                      leaveq 
400517: c3                      retq   
400518: 0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
40051f: 00 

奇妙なことに、このプログラムは関数を呼び出すときに壊れprintf()ます。ただし、N を 512 と定義すると、このプログラムはうまく機能します。理由がわかりません。スタックによるメモリ使用を制限するスタック サイズの制限はありますか?

理由を知っている人はいますか?ありがとう。

4

4 に答える 4

2

スタック サイズの超過によるエラー。これを取り除くには、配列をヒープに作成します。これを行うには、mallocまたはその他の動的メモリ割り当て関数を使用します。

このよう int *a = malloc(N*N*sizeof(int))に、メモリはヒープに配置されます。
また、以下を確認して、このメモリが割り当てられているかどうかをテストする必要があります。

if(a)
     // do stuff with a
于 2013-01-15T06:23:57.603 に答える
1

はい、小さい最大スタックサイズがあり、ほとんどの場合、数より小さいですKBs1024*1024*sizeof(int)=4194304bytesまたは4MBsデータを単一のスタック割り当てに割り当てようとしていますが、クラッシュが発生しています。

これに対抗するには 2 つの方法があります。

1) スタック外にメモリを割り当てる

#include<stdio.h>
#define N 1024

int a[N][N];
int b[N][N];    

int main()
{
    printf("hello world\n");
    return 0;
}

main()または 2) 以下を使用して、内部のヒープからメモリを動的に割り当てますmalloc()

    #include<stdio.h>
    #define N 1024

    int main()
    {
        int **a = malloc(N, sizeof(int*));
        int **b = malloc(N, sizeof(int*));
        for (int i=0; i<N; i++)
        {
          a[i]=malloc(N, sizeof(int));
          b[i]=malloc(N, sizeof(int));
         }
        printf("hello world\n");
        return 0;
    }

free():保持するデータの処理が完了したら、動的に割り当てられたメモリを忘れないでください。そうしないと、プログラムでメモリ リークが発生します。

于 2013-01-15T06:25:35.160 に答える
0

はい、特定の時間にスタックに割り当てることができる量には制限があります。コンパイラに依存します。Visual Studio のデフォルト サイズは 1 MB です。サイズを知るには、コンパイラの設定を確認してください。私の推測では、この制限を超えているため、クラッシュしています。

于 2013-01-15T06:23:42.837 に答える
0

ここから借りた答えを出してもいいと思います:

int (*a)[N] = malloc(N * N * sizeof(int));
int (*b)[N] = malloc(N * N * sizeof(int));

これで、元のコードの 2D 配列のようにアクセスできます。例えばa[50][100] = 37;

free(a)それらを使い終わったら、忘れないfree(b)でください。

于 2013-01-15T07:13:37.550 に答える