傻程序中的堆栈溢出异常

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)

C# setter 中的堆栈溢出异常

我在 C++ 程序中遇到堆栈溢出异常

为啥这个 BigInteger 值会导致堆栈溢出异常? C#

.NET 异常处理程序导致 Visual C++ 6.0 异常的堆栈溢出

vb 堆栈溢出