1

C++ の問題に取り組んでいますが、スタック オーバーフロー例外が発生し、その理由がわかりません。メイン メソッドは problem28() を呼び出しますが、最初の行で出力に "check" が出力されるはずですが、これは発生していません。gridsize を 501 以下に定義すると問題なく動作しますが、それ以上になるとスタック オーバーフロー例外がスローされます。

どんな助けでも大歓迎です。

#define right 0
#define down 1
#define left 2
#define up 3
#define gridsize 1001

int* next(int row, int col, int dir) {
    int* newPos = new int[2];
    newPos[0] = row;
    newPos[1] = col;
    switch(dir) {
    case right:
        newPos[1] += 1;
        break;
    case down:
        newPos[0] += 1;
        break;
    case left:
        newPos[1] -= 1;
        break;
    case up:
        newPos[0] -= 1;
        break;
    }
    return newPos;
}

int problem28() {
    cout << "check" << endl;
    int grid[gridsize][gridsize];
    for (int i = 0; i < gridsize; i++)
        for (int j = 0; j < gridsize; j++)
            grid[i][j] = 0;
    int* pos = new int[2];
    pos[0] = pos[1] = gridsize / 2;
    int dir = right;


    for (int i = 1; i <= 1001; i++) {
        grid[pos[0]][pos[1]] = i;
        pos = next(pos[0], pos[1], dir);
        int* npos;

        npos = next(pos[0], pos[1], (dir + 1) % 4);
        if (grid[npos[0]][npos[1]] == 0)
            dir = (dir + 1) % 4;
    }
    cout << "generated grid" << endl;

    int total = 0;
    for (int i = 0; i < gridsize; i++) {
        total += grid[i][i];
        total += grid[i][gridsize - i - 1];
    }
    total -= grid[gridsize / 2][gridsize / 2];

    return 0;
}

int main() {
    problem28();

    system("pause");
    return EXIT_SUCCESS;
}
4

4 に答える 4

3

通常、スタックはメモリ全体に比べてかなり制限されています。problem28再帰的ではないように見えるため、最も簡単に動作する可能性が最も高い修正方法は、次のように変更することです。

int grid[gridsize][gridsize]; 

に:

static int grid[gridsize][gridsize];

これにより、その配列のメモリがローカルではなく静的に割り当てられます。これは通常、スタック上にないことを意味します。

もう 1 つの可能性はstd::vector、配列の代わりに a を使用することです。これは通常、ローカルではなくフリー ストアからメモリを割り当てます。マイナーな問題は、vector(それ自体では) 2D アドレッシングを提供しないため、それを個別に処理する必要があることです (たとえば、前の回答で投稿したarray_2Dを使用します)。

于 2012-12-12T19:32:34.220 に答える
1

gridsize を 501 以下に定義すると問題なく動作しますが、それ以上になるとスタック オーバーフロー例外がスローされます。

配列全体gridがスタック上に存在します。int32 ビット幅の場合、int[500][500]約 1MB かかります。これは、一部のオペレーティング システムのデフォルトの最大スタック サイズです。

スタックのサイズを増やすか、(できれば)gridヒープに割り当てることができます。

于 2012-12-12T19:31:24.153 に答える
0

問題はここにあるようです:

int grid[gridsize][gridsize];

この 2D 配列を動的に割り当ててみましたか?

于 2012-12-12T19:32:14.640 に答える
0

Application Verifier などのプログラムを使用して、クラッシュの原因となっている問題を見つけることをお勧めします。

アプリケーション検証ツールのダウンロード

ソフトウェアをデバッグする方法を学び、何が起こっているのかを理解することが重要です。デバッガー (Visual Studio、Eclipse) でコードを実行し、停止する場所を確認してください。Application Verifier を使用した場合は、問題が発生した場所で停止する可能性があります。変数を見て、意味があるかどうかを確認してください。すべきではないメモリの場所にアクセスしているかどうかを確認します。

Visual Studio で Application Verifier を使用するには、それをインストールしてから、C:\Windows の System32 フォルダーで appVerifier.exe を見つけます。次に、ファイルを開き、実行可能ファイルをポイントします。適切なチェックと思われるものを有効にします。次に、Visual Studio で実行します。

Linux の場合、valgrind を使用してこの種の問題を検出できます (使用する必要があります)。

于 2012-12-12T20:13:23.153 に答える