2012-05-10 137 views
6

我使用VS 2010
当我在调试模式下运行此程序,它会引发堆栈溢出异常,并显示在行在文件chkstk.asm一个特征线99
但当我在释放模式下运行它时没问题。
此外,如果我将其中一个数组的大小减少到10000,它在调试中效果很好。是什么原因?堆栈溢出异常

#include <iostream> 

using namespace std; 
int main() 
{ 
    char w[1000001], temp[1000001]; 
    cout<<"Why?"<<endl; 
    return 0; 
} 
+3

您在发布模式中启用了哪些优化?编译器很有可能只是删除数组。 –

+0

可能的重复[调试堆栈溢出,但不是在发布](http://stackoverflow.com/questions/5670904/stack-overflow-when-debugging-but-not-in-release) –

+0

你问“什么是溢出的原因?“或者“行为在不同构建模式下变化的原因是什么?”或者是其他东西? –

回答

11

由于堆栈非常小,在大多数系统上大约为1MB,所以您将使用大型缓冲区溢出堆栈。要解决这个问题,只需像这样在堆上分配:

#include <iostream> 

using namespace std; 
int main() 
{ 
    char* w = new char[1000001]; 
    char* temp = new char[1000001]; 
    cout<<"Why?"<<endl; 
    delete[] w; 
    delete[] temp; 
    return 0; 
} 
+2

或使用'std :: vector'就像其他人已经建议的! –

5

堆栈很小(〜1MB)。你用这些数组中的大量元素填充它。

如果您需要更多空间,请尝试在堆上分配(哪些指针会这样做)。

实现这个的一个好方法是用向量,在堆上其内部存储的东西:

std::vector<char> w (1000001); 
std::vector<char> temp (1000001); 
4

阵列在自动存储在栈上分配的。堆栈空间有限。当堆栈空间不足以分配自动变量时,会发生堆栈溢出异常。

如果您需要大的数组,请改为使用静态或动态分配。

对于静态分配,将声明移至main()以外。

对于动态分配,使用下面的代码:

char *w = new char[1000001], *temp = new char[1000001]; 
// Work with w and temp as usual, then 
delete[] w; 
delete[] temp; 

最后,可以考虑使用,而不是简单的阵列标准集装箱:std::array是一个更好的数组,如果你不需要调整(这是在栈上分配的,并不会解决这个问题); std::string也是取代char阵列的好候选者。

+2

我不认为'std :: array'会解决他的问题。它将*仍然*在堆栈上分配数据。试试'std :: vector'。 –

+0

@Robᵩ你是对的,它不会!我提到'std :: array'作为普通数组的替代品,而不是解决这个特定问题的方法。我可以看到这部分答案可能会产生误导,所以为了清晰起见我对其进行了编辑。谢谢! – dasblinkenlight

5

你正在堆栈上分配太多东西;可能在调试模式下,堆栈因各种安全检查而被占用更多,或故意较小以帮助您在早期检测到此类问题。无论如何,使数组稍微大一些,即使在发布模式下也会触发堆栈溢出(除非编译器完全优化它们)。

问题的根源在于你不应该在堆栈上分配大的东西,这个堆栈的大小是非常有限的(默认情况下在VC++上为1MB),并且只能用于小缓冲区/对象。如果您需要大量分配,请在堆上执行(使用new/malloc),最好使用智能指针来避免内存泄漏。