visualc++程序停止工作时,数组的大小太大

visual C++ program stops working when the array size is too large

本文关键字:数组 程序 停止工作 visualc++      更新时间:2023-10-16

我在MVC++ 2010中编写了c++代码。在它内部,程序遍历一维指针数组(double *)的元素。然而,当我使输入(指针数组的大小)非常大,例如15000,并运行程序,它停止工作,并显示一个窗口关闭程序,因为它没有响应!有什么问题吗?

下面是构建我正在谈论的数组的部分代码:
map<int, double *> CF;
CoefficientMap(CF);
double *T = new double[I * J];
for (int r = 1; r <= I * J; ++r)
    T[r] = 100;
SOR(T, CF, 1.8);

,这是迭代器函数:

void SOR(double *T, map<int, double *> &CF, double w)
{
int iter = 0;
cout << "Stage 2: Solving the linear system of equations using SOR method... ";
const double tol = 0.00001;
double error = tol + 1;
double *TOld = new double[I * J];
for (int i = 1; i <= I * J; ++i)
    TOld[i] = 100;
while (abs(error) > tol)
{
    ++iter;
    for (int i = 1; i <= I * J; ++i)
        T[i] = (CF[i][0] + CF[i][1] * T[i + 1] + CF[i][2] * T[i + J] + CF[i][3] * T[i - J] + CF[i][4] * T[i - 1]) * w + (1 - w) * T[i];
    error = errorCalc(TOld, T, I * J);
    for (int i = 1; i <= I * J; ++i)
        TOld[i] = T[i];
    if (iter % 100 == 0)
    {
        cout << endl << endl;
        cout << "100 iterations done, please wait..." << endl << "Total accumulative error till this point: " << error << endl;
    }
    if (iter > 10000)
        return;
}
cout << "Done!" << endl << endl;
cout << "Converged after " << iter << " iterations!" << endl;
cout << "Final accumulative error: " << error << endl << endl;

}

现在,当(I * J)变得足够大(例如15000)时,程序停止工作!

最可能的解释是耗尽了堆栈空间。简单的解决方法是将数组设置为静态或全局。您也可以使用堆中的new来分配它。都将数组移出堆栈

最好的方法可能是使用智能指针并将其放到堆中:

std::unique_ptr<double[]> arrayOfDoubles(new double[size]);

当智能指针变量超出作用域时,将负责释放内存,不需要手动删除。

为了得到更好的答案,请编辑问题以包含代码…


您添加的代码至少有数组索引问题。索引从0开始,一直到数组大小- 1。正确的循环:

double *T = new double[I * J];
for (int r = 0; r < I * J; ++r)
    T[r] = 100;

你在其他循环中也有相同的错误,相同的修复。

可选修复:如果你想从1开始索引(比如,因为你有这样写的伪代码算法,不想改变索引),最简单的方法是分配一个更大的数组,不使用索引0:

double *T = new double[I * J + 1];

你可以使用你的电流循环。


这种由一个数组元素造成的缓冲区溢出是很糟糕的,因为通常在分配的内存块的末尾可能会有未使用的空间,所以在更改数组大小和未使用的空间消失之前,错误可能完全不会被注意到。即使溢出导致堆损坏,也可能不会被注意到,直到更改代码和损坏的影响发生变化。例如,如果你运气不好,添加调试代码可能会隐藏问题。

听起来像是在堆栈上分配一个普通数组,像这样:

void f()
{
    double a[123456];
    ...
}

堆栈的大小是有限的-您应该使用new或(更好)使用std::vector分配。

您在堆栈上分配了太多空间,因此没有足够的内存来满足您的请求。作为一种替代方法,您可以为对象指定静态存储时间,或者您可以使用new:

将其放在免费存储中。
std::unique_ptr<int[]> ptr(new int[size]);