1

I am implementing a Matrix with a generic vector of generic vectors (vector<vector<T>>).
My constructor receives a vector of vectors and initializes the data member using the CCTOR the library provides. When I am trying to initialize the matrix with aggregate initialization, the following line of code works:
Matrix<int> mat({ {1, 2, 3} });
But the next one doesn't:
Matrix<int> mat({ {1, 2, 3}, {4, 5 ,6} });
There is no error. Just a seemingly infinite loop.
I am clearly missing something here. What is my mistake?

Here is my matrix definition:

template<class T>
class Matrix {
private:
    int _height;
    int _length;
    vector<vector<T>> _val;
public:
    Matrix(vector<vector<T>> val) throw (const char*) :_height(val.size()), _length((*val.begin()).size()), _val(val) {
        // Checking if the rows are of different sizes.
        vector<vector<T>>::iterator it = val.begin();
        it++;
        while (it != val.end()) {
            if ((*it).size() != _length) {
                throw "EXCEPTION: Cannot Create Matrix from Vectors of Different Sizes.";
            }
        }
    }
}

There is also an output function, but I don't think that has anything to do with it.

Omer Lubin
  • 551
  • 2
  • 8
  • 24

1 Answers1

2

There's an infinite loop in your definition of the Matrix constructor, because you're not updating your iterator.

In this part of your code

while (it != val.end()) {
        if ((*it).size() != _length) {
            throw "EXCEPTION: Cannot Create Matrix from Vectors of Different Sizes.";
        }
    }

You look at the first element of the vector, and compare it to _length, then check if you're at the end of your vector again, without moving the iterator.

To fix this, change your Constructor to this:

Matrix(vector<vector<T>> val) throw (const char*) :_height(val.size()), _length((*val.begin()).size()), _val(val) {
    // Checking if the rows are of different sizes.
    auto it = val.begin();
    while (it != val.end()) {
        if ((*it).size() != _length) {
            throw "EXCEPTION: Cannot Create Matrix from Vectors of Different Sizes.";
        }
        ++it; // this line is added
    }
}

This way your iterator will be updated every loop. Also note that throw (const char*) is deprecated. Consider using noexcept(false) instead. And while you're at it, single argument constructors should be marked explicit to avoid implicit type conversions.

EDIT: Also worth a look: Why is “using namespace std” considered bad practice?

L. Kue
  • 473
  • 5
  • 19