简体   繁体   English

C ++程序中的堆栈溢出错误

[英]stack overflow error in C++ program

So i have this complex class , and i want to have an 2d array of complex numbers this is part of the code not all the code 所以我有这个复杂的类,我希望有一个复数的二维数组,这是代码的一部分而不是所有的代码

class Complex {
public:
    /* construction/destruction */
    Complex(double r, double i)     { this->r = r; this->i = i; }
    Complex()                       { r=0.0; i=0.0; }
    ~Complex()                      { r=0.0; i=0.0; }
        /* operations */
    Complex operator+(Complex &c)   { return Complex( r+c.r, i+c.i ); }
        double r, i;
};

int main()
{
const int HEIGHT = 256;
const int WIDTH = 256;
Complex G[HEIGHT][WIDTH];
}

so the line Complex G[HEIGHT][WIDTH]; 所以行复G [HEIGHT] [WIDTH]; is the line that causes the problem , any idea why ? 是导致问题的线,任何想法为什么?

Visual studio defaults to 1MB stack size, it looks like: Visual Studio默认为1MB堆栈大小,它看起来像:

Complex G[HEIGHT][WIDTH];

will be just about 1MB, you can modify this using /F and the document says ( emphasis mine ): 将只有大约1MB,你可以使用/ F修改它,文件说( 强调我的 ):

Without this option the stack size defaults to 1 MB . 如果没有此选项,堆栈大小默认为1 MB The number argument can be in decimal or C-language notation. number参数可以是十进制或C语言表示法。 The argument can range from 1 to the maximum stack size accepted by the linker. 参数的范围可以从1到链接器接受的最大堆栈大小。 The linker rounds up the specified value to the nearest 4 bytes. 链接器将指定值向上舍入为最接近的4个字节。 The space between /F and numberis optional. / F和number之间的空格是可选的。

The most obvious alternative would be to use dynamic memory allocation via new or std::vector . 最明显的替代方案是使用newstd :: vector进行动态内存分配。

Visual Studio as far as I know actually has one of the smaller default stack sizes: 据我所知, Visual Studio实际上有一个较小的默认堆栈大小:

platform    default size       
=====================================
SunOS/Solaris  8192K bytes
Linux          8192K bytes
Windows        1024K bytes
cygwin         2048K bytes
Mac OS X       8192K bytes

Any idea why? 知道为什么吗?

Some compilers default the stack size to 1MB. 一些编译器将堆栈大小默认为1MB。 You are allocating 65536 Complex objects that occupies 2 * sizeof(double) memory each. 您正在分配65536 Complex对象,每个对象占用2 * sizeof(double)内存。 Assuming double to be 8 bytes (this information is implementation defined) you are effectively trying to allocate 16 * 65536 bytes (without considering possible paddings), which are 1048576 bytes, that causes the overflow. 假设double为8个字节(此信息是实现定义的),您实际上正在尝试分配16 * 65536个字节(不考虑可能的填充),这是1048576个字节,导致溢出。

An alternative is using dynamic allocation with a wrapper, that simulates a bi-dimensional array indexing, along the lines of this one: 另一种方法是使用包装器进行动态分配,该包装器模拟一个二维数组索引,沿着这一行:

template<std::size_t A, std::size_t B>
class G {
private:
    std::unique_ptr<Complex[]> mem;
public:
    G() : mem(new Complex[A * B]) {}
    Complex& operator()(std::size_t a, std::size_t b) {
        return mem[a * B + b];
    }
    Complex  operator()(std::size_t a, std::size_t b) const {
        return mem[a * B + b];
    }
};

Then you program simply becomes: 那么你的程序就变成了:

int main(int, char*[]) {
    G<256, 256> g;
    g(0, 0) = ...;
}

Of course you can generalize your wrapper G for a generic type with templates, but that's outside the scope of this answer. 当然,您可以将包装器G概括为带有模板的泛型类型,但这超出了本答案的范围。


On a side note, you destructor: 在旁注,你析构函数:

~Complex() { r=0.0; i=0.0; }

is useless. 没用。 Don't re-initialize memory that will be destroyed anyway when it leaves the scope. 不要重新初始化当它离开作用域时将被销毁的内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM