所以我有这个复杂的类,我希望有一个复数的二维数组,这是代码的一部分而不是所有的代码
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];导致问题的那条线,任何想法为什么?
答案 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; }
没用。不要重新初始化当它离开示波器时将被销毁的内存。