"Vector subscript out of range",在return声明?

"Vector subscript out of range", at return statement?

我的程序在 return 语句中引发 "vector subscript out of range" exceptionEDIT: 断言)。好吧,它似乎是因为它恰好在那个断点上引发了它。

这是导致它的函数:

Matrix4 Perspective(float fov, float aspect, float near, float far) const {
    double yScale = 1.0 / tan(TO_RADIANS * fov / 2);
    double xScale = yScale / aspect;
    double depth = near - far;

    Matrix4 perspective;

    perspective[0][0] = xScale;
    perspective[1][1] = yScale;
    perspective[2][2] = (far + near) / depth;
    perspective[2][3] = 2 * far * near / depth;
    perspective[3][2] = -1;
    perspective[3][3] = 0;

    return perspective; // Raises exception here?
}

我的默认 Matrix4 构造函数很好,它基本上是这样做的:

_matrix.resize(4);

for (unsigned int i = 0; i < 4; ++i)
    _matrix[i].resize(4);

_matrix 是一个 std::vector<std::vector<float>> 属性。所以一切都设置为0.

最后,使用return语句结果的那段代码是这样的:

Matrix4 camera = Perspective(70, 1, 0.2, 10);

而且我有一个看起来也不错的复制构造函数:

Matrix4(const Matrix4& matrix) {

    _matrix.reserve(4);

    for (unsigned int i = 0; i < 4; ++i) {
        _matrix[i].reserve(4);

        for (unsigned int j = 0; j < 4; ++j)
            _matrix[i][j] = matrix[i][j];
    }
}

(我也有一个重载的operator[],但问题确实不是它引起的。)

exception 断言似乎是在 return perspective; 上引发的,但它可能是由调用该方法的代码行引发的,以及不知何故的复制构造函数复制失败?但在那种情况下,Visual Studio 应该将我带入构造函数,因为我正在使用详细的逐步...

此时我迷路了...

在你的复制构造函数中,改变这个:

_matrix.reserve(4);

对此:

_matrix.resize(4);

因为您想实际分配 space 与 vector::resize, in order for _matrix[i][j] = matrix[i][j]; to work smoothly. vector::reserve 设置向量的容量。

vector resize VS reverse 阅读更多内容。

您错误地使用了 reserve 而不是 resize

但是您可以将复制构造函数简化为

Matrix4(const Matrix4& rhs) : _matrix(rhs._matrix) {}

甚至,如果适用:

Matrix4(const Matrix4&) = default;

你有一个常见的错误。 std::vector::reserve:

[i]ncrease[s] the capacity of the vector

,而不是大小,因此您必须在保留后使用 push_back,或者像在普通构造函数中一样使用调整大小。