傻程序中的堆栈溢出异常
Posted
技术标签:
【中文标题】傻程序中的堆栈溢出异常【英文标题】:Stack overflow exception in the silly program 【发布时间】:2012-05-10 21:39:11 【问题描述】:我正在使用 VS 2010。 当我在调试模式下运行此程序时,它会引发堆栈溢出异常并在文件 chkstk.asm 的第 99 行显示断线。 但是当我在 Release 模式下运行它时,它就可以了。 此外,如果我将其中一个数组的大小减小到 10000,它在 Debug 中运行良好。是什么原因?
#include <iostream>
using namespace std;
int main()
char w[1000001], temp[1000001];
cout<<"Why?"<<endl;
return 0;
【问题讨论】:
您在发布模式下启用了哪些优化?编译器很有可能只是删除了数组。 Stack overflow when debugging but not in release 的可能重复项 您是在问“溢出的原因是什么?”或者“行为在不同构建模式下发生变化的原因是什么?”还是别的什么? 作为我找到的可能的解决方案#pragma comment(linker, "/STACK:1000000000") 它在调试模式下崩溃,因为您在堆栈上分配了太多变量。它不会在 RELEASE 模式下崩溃,因为编译器认识到您甚至没有使用 w 和 temp 并将它们优化为不存在。如果它们不存在,则不会占用堆栈空间,也不会导致堆栈溢出。 【参考方案1】:由于堆栈非常小,在大多数系统上大约为 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】:堆栈非常小(~1MB)。您正在用这些数组中的大量元素填充它。
如果您需要更多空间,请尝试在堆上分配(指针会这样做)。
实现这一点的一个好方法是使用向量,它在内部将东西存储在堆上:
std::vector<char> w (1000001);
std::vector<char> temp (1000001);
【讨论】:
【参考方案3】:你在堆栈上分配了太多东西;可能在调试模式下,堆栈由于各种安全检查而被占用更多,或者故意变小以帮助您更早地检测到此类问题。无论如何,即使在释放模式下,使数组稍大一点也会触发堆栈溢出(除非编译器完全优化它们)。
这里问题的根源是您不应该在堆栈上分配大的东西,堆栈的大小非常有限(在使用 VC++ 的 Windows 上默认为 1 MB)并且应该只用于小缓冲区/对象。如果您需要进行大分配,请在堆上进行(使用new
/malloc
),最好使用智能指针以避免内存泄漏。
【讨论】:
【参考方案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
数组的不错选择。
【讨论】:
我认为std::array
不会解决他的问题。它将仍然在堆栈上分配数据。试试std::vector
。
@Robᵩ 你是对的,它不会!我提到std::array
作为普通数组的替代品,而不是解决这个特定问题的方法。我可以看到答案的这一部分可能会产生误导,因此为了清楚起见,我对其进行了编辑。谢谢!以上是关于傻程序中的堆栈溢出异常的主要内容,如果未能解决你的问题,请参考以下文章
winsock 选择函数中的堆栈溢出异常 (0xC00000FD)
为啥这个 BigInteger 值会导致堆栈溢出异常? C#