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

时间:2013-11-27 04:40:53

标签: c++ class visual-c++ pointers

所以我有这个复杂的类,我希望有一个复数的二维数组,这是代码的一部分而不是所有的代码

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];
}

所以行复G [HEIGHT] [WIDTH];导致问题的那条线,任何想法为什么?

2 个答案:

答案 0 :(得分:7)

Visual Studio默认为1MB堆栈大小,它看起来像:

Complex G[HEIGHT][WIDTH];

只需1MB左右,您可以使用/F进行修改,文档说明(强调我的):

  

如果没有此选项,堆栈大小默认为1 MB 。 number参数可以是十进制或C语言表示法。参数的范围可以从1到链接器接受的最大堆栈大小。链接器将指定值向上舍入为最接近的4个字节。 / F和number之间的空格是可选的。

最明显的选择是通过 new std::vector使用动态内存分配。

据我所知,

Visual Studio 实际上有one of the smaller default堆栈大小:

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

答案 1 :(得分:1)

  

知道为什么吗?

某些编译器将堆栈大小默认为1MB。您正在分配65536个Complex个对象,每个对象占用2 * sizeof(double)个内存。假设double为8个字节(此信息是实现定义的),您实际上正在尝试分配16 * 65536个字节(不考虑可能的填充),这是1048576个字节,导致溢出。

另一种方法是使用包装器进行动态分配,该包装器模拟一个二维数组索引,沿着这一行:

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];
    }
};

然后你的程序就变成了:

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

当然,您可以将包装器G概括为包含模板的泛型类型,但这超出了本答案的范围。


另一方面,你是析构函数:

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

没用。不要重新初始化当它离开示波器时将被销毁的内存。