-1

So I'm trying to overload the operator + in a template class. the code compiles and runs but crashes at the use of the operator +. tried so many things, I think it's a syntax problem? any advice would be appreciated!

The operator = is overloaded and works.

Matrix.h

template <int row, int col, class T = int>
class Matrix
{
    int rows;
    int cols;
    T** mat;

public:

    Matrix(int defVal = 0) {
        rows = row;
        cols = col;
        memory();

        for (int i = 0; i < rows; i++)
            for (int j = 0; j < cols; j++)
                mat[i][j] = defVal;
    }
    ~Matrix() {
        del();
    }

    Matrix(const Matrix& other) {
        *this = other;
    }

    const Matrix& operator=(const Matrix& other) {
        if (&other != this)
        {   
            rows = other.rows;
            cols = other.cols;
            del();
            memory();
            for (int i = 0; i < rows; i++)
                for (int j = 0; j < cols; j++)
                    mat[i][j] = other.mat[i][j];
        }
        return *this;
    }

    friend ostream& operator<<(ostream& os, const Matrix& m) {

        for (int i = 0; i < m.cols; i++)
        {
            for (int j = 0; j < m.rows; j++)
                os << m.mat[i][j] << " ";
            os << endl;
        }
        return os;
    }

    friend Matrix operator+(const Matrix& other, T num) {

        Matrix temp = other;

        for (int i = 0; i < temp.rows; i++)
            for (int j = 0; j < temp.cols; j++)
                temp.mat[i][j] += num;
        return temp;
    }

    void memory(){
        mat = new T * [rows];
        for (int i = 0; i < rows; i++)
            mat[i] = new T[cols];
    }

    void del(){
        for (int i = 0; i < rows; i++)
            delete[] mat[i];
        delete[] mat;
    }
};

main.cpp

int main() {

    Matrix<4, 4> mat;
    std::cout << mat << std::endl;

    Matrix<4, 4> identity(1);

    std::cout << identity + 3 << std::endl; //crashes here

return 0;
}

if you need other parts of the code let me know! Thanks in advance!

1 Answers1

1

Your copy constructor and assignment looks suspicious, you del after changing rows and cols, without initialising anything. I expect it should be

Matrix(const Matrix& other) : rows(0), cols(0), mat(nullptr) {
    *this = other;
}

const Matrix& operator=(const Matrix& other) {
    if (&other != this)
    {   
        del(); // clean up first
        rows = other.rows;
        cols = other.cols;
        memory();
        for (int i = 0; i < rows; i++)
            for (int j = 0; j < cols; j++)
                mat[i][j] = other.mat[i][j];
    }
    return *this;
}

As an aside, I wouldn't use dynamic allocation here at all, and instead

template <typename T, size_t rows, size_t cols>
class Matrix
{
    std::array<std::array<T, cols>, rows> mat;
public:
    Matrix(T defVal = {}) {
        for (int i = 0; i < rows; i++)
            for (int j = 0; j < cols; j++)
                mat[i][j] = defVal;
    }

    friend std::ostream& operator<<(std::ostream& os, const Matrix& m) {
        for (int i = 0; i < cols; i++)
        {
            for (int j = 0; j < rows; j++)
                os << m.mat[i][j] << " ";
            os << std::endl;
        }
        return os;
    }

    friend Matrix operator+(Matrix other, T num) {
        for (int i = 0; i < rows; i++)
            for (int j = 0; j < cols; j++)
                other.mat[i][j] += num;
        return other;
    }

    // No need for any special members
};
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • well, it's homework so I have to use dynamic memory allocation. i fixed the copy ctor and it worked! can you please explain me how you knew the problem is there? in what part of the code I used the copy ctor? @Caleth – Shahar Stahi Jul 29 '19 at 16:08
  • @ShaharStahi because you have the `row` and `col` template parameters, you don't actually need `rows` and `cols` as data members. An alternative that would have allocation is `std::unique_ptr mat;` – Caleth Jul 29 '19 at 16:16