为什么在为 Matrix class 实现初始化列表构造函数时无法访问此数组?

Why can I not access this array whilst implementing an initializer list constructor for a Matrix class?

我正在使用实现矩阵的旧代码库。我正在尝试添加一种方法来启用从初始化列表进行构造。我很困惑,因为这是昨天的工作。我不确定我通过此代码更改的内容在到达 _Array[row * col + col] = r.begin()[col]; 时会崩溃和烧毁。为什么我无法访问此 _Array

这是一个抽象的例子:

#include <initializer_list>
#include <iostream>

template<class T>
class Matrix {

    void resize(unsigned int rows, unsigned int cols) {
        if (rows * cols != _Rows * _Cols) {
            if (_Array) {
                delete[] _Array;
                _Array = nullptr;
            }
            if (rows && cols) {
                _Array = new T[rows * cols];
            }
        }

        _Rows = rows;
        _Cols = cols;
    }

    /**
     * number of rows
     */
        unsigned int _Rows;

    /**
     * number of columns
     */
    unsigned int _Cols;

    /**
     * pointer to block of memory of the data, stored in row-major format.
     */
    T *_Array;

public:
    Matrix<T>(std::initializer_list<std::initializer_list<T>> matrix)
        : _Array(nullptr) {
        _Rows = matrix.size();
        _Cols = (*matrix.begin()).size();
        resize(_Rows, _Cols);

        for (int row = 0; row < _Rows; row++) {
            const std::initializer_list<T> &r = matrix.begin()[row];
            for (int col = 0; col < _Cols; col++) {
                printf("Row: %d; col: %d; value: %d", row, col, r.begin()[col]);
                _Array[row * col + col] = r.begin()[col];
            }
        }
    }
};

int main(){
    Matrix<int> matrix(
            {
                    {1, 2, 3},
                    {4, 5, 6},
            });
}

clion 输出:

AddressSanitizer:DEADLYSIGNAL
Row: 0; col: 0; value: 1
Process finished with exit code 6

P.S。我很想只使用 STL 类型,但这不是一个选项,而且我知道在变量名前加上下划线的错误做法。

您将所有内容初始化为无效状态

_Array = nullptr
_Rows = matrix.size();
_Cols = (*matrix.begin()).size();

这是不正确的,因为您的代码假设 _Rows 和 _Cols 是关于 _Array 的准确元数据。

然后你要求调整大小什么都不做

resize(_Rows, _Cols);

void resize(unsigned int rows, unsigned int cols) {
    if (rows * cols != _Rows * _Cols) {
        // unreachable code
    }
    // redundant you already set these
    _Rows = rows;
    _Cols = cols;
}

因此 _Array 将始终为 nullptr,然后您通过尝试将其用作数组指针来取消引用。