std::vector 的奇怪行为
Strange behavior with std::vector
我正在尝试使用 std::vector 实现矩阵模板 class。
代码:
// matrix.h
template <class T>
class matrix
{
public:
~matrix(void);
matrix(int rows, int cols):_rows(rows),_cols(cols){ _size = _rows*_cols;init();} //
private:
matrix(void);
void init(); // sets up _matirx
//DATA
size_t _rows;
size_t _cols;
std::vector<T> _matrix;
}
// continued in matrix.tpp file
template <class T>
void matrix<T>::init(){
_matrix = std::vector<T>(_rows*_cols);
for(size_t i = 1; i <= _rows ;i++){
for(size_t j = 1 ; j <= _cols ; j++){
_matrix[(i - 1)*_rows + (j - 1 )] = 0 ;
}
}
}
template <class T>
matrix<T>::matrix(const matrix<T>& rhs)
{
_matrix = rhs._matrix;
_rows = rhs._rows;
_cols = rhs._cols;
}
//in Source.cpp
matrix<int> ABC = matrix<int>(4,2) ;
// Gives Debug Assertion Failed , subscript error in VS
matrix<int> ABC = matrix<int>(4000,4000) ;// Works , No Error
matrix<int> ABC = matrix<int>(2,4) ; // Works No Error
我知道如何使用 push_back,我将使用它重新实现 class,但我想知道,为什么它在后两种情况下有效,而在第一种情况下无效?我的直觉是,在第一种情况下,某些元素没有被初始化。 std::vector 中是否存在限制,即对于索引 i,必须在初始化 i+2 元素之前初始化第 i+1 个元素?
还是有更微妙的事情发生?
- 谢谢
这里你可能有越界访问:
_matrix = std::vector<T>(_rows*_cols);
for(size_t i = 1; i <= _rows ;i++){
for(size_t j = 1 ; j <= _cols ; j++){
_matrix[(i - 1)*_rows + (j - 1 )] = 0 ;
}
}
在最后一个循环执行期间以你的例子为例:
- 4x2 大小:i-1 = 3,_rows = 4 和 j-1 = 1,因此您正在访问大小为 8 的向量的第 13 个元素。
- 对于 4000x4000 大小,您正在访问第 (4000-1)*4000+(4000-1)=15999999 个超过 16000000 的元素,因此没有越界访问。
最后一个例子也是如此。
简单的错字。
_matrix[(i - 1)*_rows + (j - 1 )] = 0 ;
应该是
_matrix[(i - 1)*_cols + (j - 1 )] = 0;
在纸上完成循环的每次迭代都会揭示这一点。
我正在尝试使用 std::vector 实现矩阵模板 class。
代码:
// matrix.h
template <class T>
class matrix
{
public:
~matrix(void);
matrix(int rows, int cols):_rows(rows),_cols(cols){ _size = _rows*_cols;init();} //
private:
matrix(void);
void init(); // sets up _matirx
//DATA
size_t _rows;
size_t _cols;
std::vector<T> _matrix;
}
// continued in matrix.tpp file
template <class T>
void matrix<T>::init(){
_matrix = std::vector<T>(_rows*_cols);
for(size_t i = 1; i <= _rows ;i++){
for(size_t j = 1 ; j <= _cols ; j++){
_matrix[(i - 1)*_rows + (j - 1 )] = 0 ;
}
}
}
template <class T>
matrix<T>::matrix(const matrix<T>& rhs)
{
_matrix = rhs._matrix;
_rows = rhs._rows;
_cols = rhs._cols;
}
//in Source.cpp
matrix<int> ABC = matrix<int>(4,2) ;
// Gives Debug Assertion Failed , subscript error in VS
matrix<int> ABC = matrix<int>(4000,4000) ;// Works , No Error
matrix<int> ABC = matrix<int>(2,4) ; // Works No Error
我知道如何使用 push_back,我将使用它重新实现 class,但我想知道,为什么它在后两种情况下有效,而在第一种情况下无效?我的直觉是,在第一种情况下,某些元素没有被初始化。 std::vector 中是否存在限制,即对于索引 i,必须在初始化 i+2 元素之前初始化第 i+1 个元素? 还是有更微妙的事情发生?
- 谢谢
这里你可能有越界访问:
_matrix = std::vector<T>(_rows*_cols);
for(size_t i = 1; i <= _rows ;i++){
for(size_t j = 1 ; j <= _cols ; j++){
_matrix[(i - 1)*_rows + (j - 1 )] = 0 ;
}
}
在最后一个循环执行期间以你的例子为例:
- 4x2 大小:i-1 = 3,_rows = 4 和 j-1 = 1,因此您正在访问大小为 8 的向量的第 13 个元素。
- 对于 4000x4000 大小,您正在访问第 (4000-1)*4000+(4000-1)=15999999 个超过 16000000 的元素,因此没有越界访问。
最后一个例子也是如此。
简单的错字。
_matrix[(i - 1)*_rows + (j - 1 )] = 0 ;
应该是
_matrix[(i - 1)*_cols + (j - 1 )] = 0;
在纸上完成循环的每次迭代都会揭示这一点。