为什么在为 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,然后您通过尝试将其用作数组指针来取消引用。
我正在使用实现矩阵的旧代码库。我正在尝试添加一种方法来启用从初始化列表进行构造。我很困惑,因为这是昨天的工作。我不确定我通过此代码更改的内容在到达 _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,然后您通过尝试将其用作数组指针来取消引用。