为什么我在Visual Studio中遇到堆栈溢出错误

Why I'm getting stack overflow error in Visual Studio

本文关键字:遇到 堆栈 栈溢出 错误 Studio Visual 为什么      更新时间:2023-10-16

我是C++初学者,不了解许多后台过程,例如编译器如何分配内存等。我正在使用Visual Studio 2013编写c ++程序。我必须使用Visual Studio,因为我将matlab链接到我的c ++代码。

我遇到堆栈溢出错误,我不知道如何删除它。当我设置 N = 100 时,我没有收到此错误,但是当我设置较大的 N 值(例如 150、200)时,我会收到堆栈溢出错误。

如果有人能指出为什么我在 VS 中出现此错误,那就太好了。我使用带有GCC编译器的代码块测试了相同的代码,这根本没有给出任何错误。

#include<iostream>
using namespace std;
const int N = 200;              //Number of grid points
int main()
{
double n = N;
double dx = 4 / (n - 1); double dy = 4 / (n - 1);
double col = n, row = n;
double dt = 0.5*dx;                             // time step size(dTau)
int itmax = 2500;                               // max iterations
int i, j, t;
double x[N] = { 0.0 }, y[N] = { 0.0 };
x[0] = -2; y[0] = -2;                           // define grid
for (i = 1; i < N; i++){
    x[i] = x[i - 1] + dx;
    y[i] = y[i - 1] + dy;
}
// Initialize variables
double phi_0[N][N], phi_new[N][N],  F_0[N][N], F_new[N][N], F[N][N],
    Fext[N][N], phi[N][N];
return 0;
}

默认情况下,Visual Studio创建一个只有几兆字节的堆栈(或者可能只有一个 - 我不记得确切了,但通常只是当前机器上内存的一小部分)。当 N 变得太大时,您只会使用更多。

一个明显的替代方法是将大型数组定义为static这样它们就不会在堆栈上。

static double phi_0[N][N], phi_new[N][N],  F_0[N][N], F_new[N][N], F[N][N],
    Fext[N][N], phi[N][N];

这将强制静态分配数组。在main这几乎没有真正的区别,因为不允许递归调用main。然而,在直接或间接递归的函数中,这可能会/会导致问题。在这种情况下,您可能希望改用std::vector,因为这将其(大部分)数据分配给免费存储,并且仅使用少量固定的堆栈内存(通常每个向量约 12-32 字节)。

您正在分配 7 个具有自动存储持续时间的double [N][N]变量,即在堆栈上。单个双精度变量的大小为 64 位(通常),即 8 字节;所以总共需要 8 * 200 * 200 * 7 = 2240000 字节 (2.13 MiB)。这可能超过了平台上帧允许的堆栈空间。

MSDN 说默认堆栈大小为 1 MiB,而您尝试分配的堆栈大小超过此值,因此出现错误。

除了 Jerry 建议的替代方案之外,您还可以选择动态、免费存储(通常在堆上)分配,这不受堆栈大小的限制。