0

我正在尝试编写一个小助手类来绘制曼德布罗分形。该类Canvas有两个二维数组,一个用于存储复平面的坐标,另一个用于|z|超过 2 所需的迭代次数。

模板参数以像素为单位指定画布的宽度和高度。现在有趣的是,使用 的参数一切正常
<500, 500>,但是如果我选择例如,<600, 600>我会遇到分段错误。array.at()我已经通过使用而不是检查和越界错误,array[]但仍然没有。

template <std::size_t W, std::size_t H>
class Canvas
{
public:
    Canvas(std::complex<double> _origin, std::complex<double> _end);
    ...


private:
    std::complex<double> origin;
    std::complex<double> end;
    std::array<std::array<std::complex<double>, H>, W> field;
    std::array<std::array<std::pair<bool, int>, H>, W> results;
};


template <std::size_t W, std::size_t H>
Canvas<W, H>::Canvas(std::complex<double> _origin, 
                     std::complex<double> _end)
    : origin{_origin}, end{_end}
{
    double delta_x {end.real() - origin.real()};
    double delta_y {end.imag() - origin.imag()};
    double step_x {delta_x / static_cast<double>(W-1)};
    double step_y {delta_y / static_cast<double>(H-1)};

    for (std::size_t w = 0; w < W; ++w)
    {
        for (std::size_t h = 0; h < H; ++h)
        {
            field[w][h].real(origin.real() + (step_x*w));
            field[w][h].imag(origin.imag() + (step_y*h));
        }
    }
}
4

2 回答 2

4

我已经运行了代码,看起来你得到的是堆栈溢出(讽刺)。您可以看到,因为它在以下位置失败:

; Find next lower page and probe

cs20:
        sub     eax, _PAGESIZE_         ; decrease by PAGESIZE
        test    dword ptr [eax],eax     ; probe page. <------ HERE
        jmp     short cs10

您还可以通过以下事实看到这一点:它在某个时间点后开始失败,在数字开始变大并将其分配到堆上解决了问题之后。您的 Canvas 对象如此巨大,因为:

std::array<std::array<std::complex<double>, H>, W> field;
std::array<std::array<std::pair<bool, int>, H>, W> results;

大小H * W * sizeof(complex<double>)H * W * sizeof(pair<bool,int>). 我建议你简单地在堆上使用这个类,并且在使用高模板数时不要在堆栈上分配它(对于 400、400,我已经失败了)。

于 2013-10-17T19:30:53.387 回答
1

我认为您的问题可能是您Canvas在堆栈上分配了 的实例。如果你有这样的事情:

void f()
{
    std::complex<double> origin( 0, 0 );
    std::complex<double> end( 100, 100 );

    Canvas< 600, 600 > cv( origin, end );
    // ...
}

您可能需要检查在堆上分配对象是否有帮助:

void f()
{
    std::complex<double> origin( 0, 0 );
    std::complex<double> end( 100, 100 );

    typedef Canvas< 600, 600 > CV
    auto cv_ptr = std::unique_ptr< CV >( new CV( origin, end ) );
    // ...
}
于 2013-10-17T19:31:02.290 回答