重载运算符*(乘法)返回不同的结果

时间:2019-07-14 18:27:24

标签: c++

我创建了class Matrix并重载了operator*用于矩阵乘法。在操作员内部,计算是正确的,但返回的结果与此不同。

我尝试将此功能从朋友功能更改为方法,但得到相同的结果。 此外,我重载了+,-等运算符,并且它们可以正常工作

#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);
}

主要

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
}

如您所见,cx是由相同数据创建的矩阵,但是得到两个不同的结果。

|22 28|
|49 64|

来自x.Print()

|4761920 4557403|
|4199040 7011960|

来自c.Print()

2 个答案:

答案 0 :(得分:5)

问题是Matrix构造函数保留了指向在堆栈(arr)上分配的对象的指针。一旦arr超出范围,任何取消引用指针的尝试都将导致undefined behaviour

您需要找到另一种方法来管理矩阵数据的生存期(例如,通过让矩阵类保留其自己的副本)。

答案 1 :(得分:0)

感谢您的回答,它使我(至少部分地)了解了这种情况。

id-match更改为T *arr解决了该问题。