2012-12-12 39 views
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; 
} 
+0

的#pragma评论(连接 “/ STACK:16777216”),这给你叠 –

回答

3

与整体内存相比,堆栈通常非常有限。由于problem28似乎没有递归,到目前为止这是最有可能工作的最简单的解决方法是改变:

int grid[gridsize][gridsize]; 

到:

static int grid[gridsize][gridsize]; 

这将分配的内存数组静态代替本地,这通常意味着它不再在堆栈上。

另一种可能性是使用std::vector而不是数组。这通常将从免费商店而不是本地分配其内存。小问题是,vector(本身)不提供二维寻址,所以你必须分开处理(例如,使用我在之前的回答中发布的array_2D)。

+1

添加'静态'做到了。谢谢您的帮助。 – excaliburHisSheath

1

如果我定义gridsize为501以下运行良好,但任何更重要的是,它抛出一个堆栈溢出异常。

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

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

+0

@phonetagger的16 MB:不是为传统值为'500'和'4',以及传统的兆字节大小。 – NPE

+0

@phonetagger:这使得你的'int' 4x4字节宽。这是我遇到的第一个2D'int'。 :) – NPE

+0

啊...是的。你达人。或女人。管他呢。 – phonetagger

0

这个问题似乎是在这里:

int grid[gridsize][gridsize]; 

你尝试动态地分配这个二维数组?

+0

我不知道你的意思是动态分配,所以你能解释一下吗? – excaliburHisSheath

+0

@ user1898872要么将网格创建为静态类成员,要么使用'new()'来防止连接堆栈。 '动态'通常意味着后者,在堆上创建一个类实例。 –

+0

将网格声明为静态,但做了'int * grid = new int [gridsize] [gridsize];'不能编译。我将如何动态分配一个二维数组? – excaliburHisSheath

0

我建议你使用一个程序,如应用程序验证程序查找导致崩溃的问题:

Application Verifier Download

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

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

对于Linux,你可以(也应该)使用的valgrind检测到这些类型的问题