Pobierac
Pobierac

Reputation: 31

Overloaded operator* (multiplication) returning different result

I created class Matrix and overloaded operator* for matrix multiplication. Inside the operator the calculations are correct but the returned result is different than this.

I tried changing this function from a friend function to a method but I got the same result. Moreover I overloaded operators like +, - and they work fine

#include <iostream>
#include <math.h>

template<typename T> class Matrix;
template<typename T> Matrix<T> operator * (const Matrix<T>&, const Matrix<T>&);

template <typename T> class Matrix
{
public:
    T *arr = nullptr;
    int r, c;
    friend Matrix<T> operator * <> (const Matrix<T>&, const Matrix<T>&);

    Matrix(T *a, int r, int c)  //parametrized constructor
    {
        this->arr = a;
        this->r = r;
        this->c = c;
    }

    void Print()
    {
        for(int i=0; i<r; i++)
        {
            std::cout<<"|";
            for(int j=0; j<c; j++)
            {
                std::cout<<*(this->arr+i*c+j)<<" ";
            }

            std::cout<<'\b';
            std::cout<<"|";
            std::cout<<std::endl;
        }
        std::cout<<std::endl;
    }

};

template <typename T> Matrix<T> operator * (const Matrix<T> &M1, const Matrix<T> &M2)
{
        int r = M2.r;
        int c = M1.c;
        int l = M1.r;
        T arr[r*c];
        for(int i=0; i<r; i++)
        {
            for(int j=0; j<c; j++)
            {
                arr[i*r+j]=0;
                for(int k=0; k<l; k++)
                {
                    arr[i*r+j]+=(M1.arr[k*r+j]*M2.arr[i*l+k]);
                }
                std::cout<<std::endl;
            }
        }
    //Matrix<T> x(arr, r, c);
    //x.Print();       -this returns correct matrix
    return Matrix<T>(arr, r, c);
}

Main

int main()
{
    //here I created matrixes a and b but skipped this part of code
    Matrix<int> c = a*b;
    c.Print();  // - this returns wrong matrix
}

As you can see, c and x are matrices created from the same data, but I'm getting two different results.

|22 28|
|49 64|

from x.Print(), and

|4761920 4557403|
|4199040 7011960|

from c.Print().

Upvotes: 1

Views: 110

Answers (2)

Pobierac
Pobierac

Reputation: 31

Thanks for answers, it let me (at least partially) understand this situation.

Changing T *arr to std::vector<T> arr solved the problem.

Upvotes: 0

NPE
NPE

Reputation: 500753

The issue is that the Matrix constructor retains a pointer to an object that's allocated on the stack (arr). Once arr goes out of scope, any attempt to dereference the pointer will result in undefined behaviour.

You need to find a different way to manage the lifetime of the matrix data (for example, by having the matrix class keep its own copy of it).

Upvotes: 5

Related Questions