nnrales
nnrales

Reputation: 1519

Strange behavior with std::vector

I am trying to implement a matrix template class using std::vector.

Code:

// 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   

I know about using push_back , I will re implement the class using it , but I was wondering , why it works in the last two cases , and does not in the first case ? My hunch is that in the first case some elements are not being initialized. Is there a restriction in std::vector that say for index i , i+1 th element has to be initialized before the i+2 element is initialized ? Or is there something more subtle going on ?

Upvotes: 1

Views: 151

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385405

Simple typo.

_matrix[(i - 1)*_rows + (j - 1 )] = 0 ;

should be

_matrix[(i - 1)*_cols + (j - 1 )] = 0;

Working it through on paper for each iteration of the loops would have revealed this.

Upvotes: 2

Hiura
Hiura

Reputation: 3530

Here you may have out-of-bounds access:

_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 ; 
    }   
}

Take your examples during the last loop execution:

  • with 4x2 size: i-1 = 3, _rows = 4 and j-1 = 1, hence you're accessing the 13-th element of your vector of size 8.
  • with 4000x4000 size, you're accessing the (4000-1)*4000+(4000-1)=15999999-th element over 16000000, hence no out of bounds access.

Same goes for the last example.

Upvotes: 1

Related Questions