1

我正在处理 C++ 中的一个问题,但是我遇到了堆栈溢出异常,我不知道为什么。主要方法调用problem28(),但第一行应该打印“检查”到我的输出,这没有发生。如果我将 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];

这将静态地而不是本地地为该数组分配内存,这通常意味着它不再在堆栈上。

另一种可能性是使用 astd::vector而不是数组。这通常会从空闲存储而不是本地分配其内存。小问题是vector(本身)不提供 2D 寻址,因此您必须单独处理(例如,使用我在上一个答案中发布的array_2D)。

于 2012-12-12T19:32:34.220 回答
1

如果我将 gridsize 定义为 501 或更少,它运行良好,但除此之外,它会引发堆栈溢出异常。

整个grid数组都存在于堆栈中。如果int是 32 位宽,int[500][500]大约需要 1MB,这恰好是某些操作系统上的默认最大堆栈大小。

您可以增加堆栈的大小,或者(最好)grid在堆上分配。

于 2012-12-12T19:31:24.153 回答
0

问题似乎在这里:

int grid[gridsize][gridsize];

您是否尝试过动态分配此二维数组?

于 2012-12-12T19:32:14.640 回答
0

我建议您使用诸如 Application Verifier 之类的程序来查找导致崩溃的问题:

应用程序验证器下载

学习如何调试软件并了解正在发生的事情很重要。请在调试器(Visual Studio、Eclipse)中运行您的代码并查看它停止的位置。如果您使用了应用程序验证程序,那么它可能会在问题所在的地方停止。看看变量,看看它们是否有意义。看看你是否正在访问你不应该访问的内存位置。

要将 Application Verifier 与 Visual Studio 一起使用,请安装它,然后在 C:\Windows 的 System32 文件夹中找到 appVerifier.exe。然后打开文件并将其指向您的可执行文件。启用您认为正确的检查。然后在 Visual Studio 中运行它。

对于 Linux,您可以(并且应该)使用 valgrind 来检测此类问题

于 2012-12-12T20:13:23.153 回答