矩阵类运算符重载、析构函数问题

发布于 2024-12-05 04:55:30 字数 2090 浏览 1 评论 0原文

我试图编写一个能够找到逆矩阵、伴随矩阵等的矩阵类。任意阶的方阵。 构造函数初始化一个 n 阶单位矩阵(传递给它)。

class Matrix
{
int** elements;
int order;

public:
Matrix& operator=(const Matrix& second_inp)
{
    if(this->order!=second_inp.order)
        cout<<"The matrix cannot be assigned!!!\n"<<this->order<<"\n"<<second_inp.order;

    else
    {
        for(int i=0;i<this->order;i++)
            for(int j=0;j<this->order;j++)
                this->elements[i][j] = second_inp.elements[i][j];

    }

    return *this;
}

Matrix operator*(const Matrix& a)const
{
    Matrix c(a.order);

    for(int i=0;i<c.order;i++)                      
        for(int j=0;j<c.order;j++)
            c.elements[i][j]=0;

    if (this->order!=a.order)
    {
        cout<<"The 2 Matrices cannot be multiplied!!!\n";
        return Matrix();
    }

    else
    {
        for(int i=0;i<a.order;i++)
            for(int j=0;j<a.order;j++)
                for(int k=0;k<a.order;k++)
                    c.elements[i][j] += (this->elements[i][k])*(a.elements[k][j]);

        return c;
    }
}
};

~Matrix()
{
    for(int i=0;i<this->order;i++)
        delete[] *(elements+i);
    delete[] elements;
    elements=nullptr;
}

如果我要使用此类运行以下代码:

Matrix exp1(2),exp2(2),exp3(2);
exp1.get_matrix();
exp3=exp1*exp2;
exp3.show_matrix();

我收到运行时错误,在调试时我发现,在乘法(exp1 * exp2)之后,=运算符无法访问数据,如果*操作员。

但是,如果我在 main() 末尾使用像这样的手动析构函数来释放所有分配的内存,则程序可以正常工作。

void destroctor()
{
  for(int i=0;i<order;i++)
    delete[] *(elements+i);
  delete[] elements;
}

我如何编辑析构函数或运算符重载来纠正此问题?

我使用的构造函数:

Matrix(int inp_order):order(inp_order)
{
    elements=new int*[order];

    for(int i=0;i<order;i++)
        *(elements+i)=new int[order];

    for(int i=0;i<order;i++)
        for(int j=0;j<order;j++)
        {
            if (i==j)
                *(*(elements+j)+i)=1;
            else
                *(*(elements+j)+i)=0;
        }
}

I was trying to write a matrix class which would be able to find inverse,adjoint,etc. of a square matrix of any order.
The constructor initializes an identity matrix of order n(passed to it).

class Matrix
{
int** elements;
int order;

public:
Matrix& operator=(const Matrix& second_inp)
{
    if(this->order!=second_inp.order)
        cout<<"The matrix cannot be assigned!!!\n"<<this->order<<"\n"<<second_inp.order;

    else
    {
        for(int i=0;i<this->order;i++)
            for(int j=0;j<this->order;j++)
                this->elements[i][j] = second_inp.elements[i][j];

    }

    return *this;
}

Matrix operator*(const Matrix& a)const
{
    Matrix c(a.order);

    for(int i=0;i<c.order;i++)                      
        for(int j=0;j<c.order;j++)
            c.elements[i][j]=0;

    if (this->order!=a.order)
    {
        cout<<"The 2 Matrices cannot be multiplied!!!\n";
        return Matrix();
    }

    else
    {
        for(int i=0;i<a.order;i++)
            for(int j=0;j<a.order;j++)
                for(int k=0;k<a.order;k++)
                    c.elements[i][j] += (this->elements[i][k])*(a.elements[k][j]);

        return c;
    }
}
};

~Matrix()
{
    for(int i=0;i<this->order;i++)
        delete[] *(elements+i);
    delete[] elements;
    elements=nullptr;
}

If i were to run the following code using this class:

Matrix exp1(2),exp2(2),exp3(2);
exp1.get_matrix();
exp3=exp1*exp2;
exp3.show_matrix();

I get a run-time error, while debugging i found out that, after the multiplication(exp1*exp2) the =operator was not able to access the data if the result of the *operator.

But if i were to use a manual destructor like this one at the end of the main() to free all allocated memory, the program works fine.

void destroctor()
{
  for(int i=0;i<order;i++)
    delete[] *(elements+i);
  delete[] elements;
}

how can i edit the destructor or the operator overloads to correct this problem?

The constructor i used:

Matrix(int inp_order):order(inp_order)
{
    elements=new int*[order];

    for(int i=0;i<order;i++)
        *(elements+i)=new int[order];

    for(int i=0;i<order;i++)
        for(int j=0;j<order;j++)
        {
            if (i==j)
                *(*(elements+j)+i)=1;
            else
                *(*(elements+j)+i)=0;
        }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╰沐子 2024-12-12 04:55:30

很难判断出了什么问题,因为您还没有发布构造函数。

exp3=exp1*exp2;中发生了很多事情:

首先在operator*函数中构造了一个新的矩阵c。然后return c;语句调用复制构造函数,然后调用析构函数。之后,operator= 被调用,然后再次调用临时矩阵的析构函数。

我认为发生的情况是您正在使用默认的复制构造函数,它不会进行深层复制。这样,在返回 c 时调用的析构函数就会删除矩阵之间仍然共享的数据。

It is hard to tell what is going wrong, since you have not posted your constructors.

In the exp3=exp1*exp2; a lot of things happen:

First a new matrix c is constructed in the operator* function. Then the return c; statement calls the copy constructor and then the destructor. After that operator= is called and after that the destructor for the temporary matrix again.

I think what happens is that you are using the default copy constructor which does not make a deep copy. That way the destructor being called at the time of return c deletes the data that still shared between the matrices.

找回味觉 2024-12-12 04:55:30

我收到运行时错误,在调试时我发现,在乘法(exp1*exp2)之后,如果 * 运算符的结果,= 运算符无法访问数据。

您没有向我们展示您的构造函数,因此无法告诉我们为什么会出现此错误。

我怀疑原因是您没有分配包含矩阵所需的内存。您将其声明为 int**,因此您需要分配一个 int* 指针数组,并且为每个指针分配一个 数组int

编辑
当我输入此内容时,您发布了构造函数的代码。

您没有从 operator* 的重载中返回值,并且没有复制构造函数(三规则)。

您是否启用了编译器警告?任何称职的编译器都会抱怨运算符重载中缺少 return 语句。

I get a run-time error, while debugging i found out that, after the multiplication(exp1*exp2) the =operator was not able to access the data if the result of the *operator.

You didn't show us your constructor, so there is no way to tell why you are getting this errors.

I suspect that the cause is that you aren't allocating the memory needed to contain your matrix. You declared it as an int**, so you need to allocate an array of int* pointers, and for each of those you need to allocate an array of int.

Edit
While I was typing this you posted code for your constructor.

You are not returning a value from your overload of operator*, and you don't have a copy constructor (rule of three).

Do you have compiler warnings enabled? Any compiler worth its salt would have complained about the missing return statement in the operator overload.

孤星 2024-12-12 04:55:30

您还没有定义复制构造函数,因此编译器将为您生成一个复制构造函数。将调用此构造函数,以便将operator*(const & Matrix a) 的返回值复制到结果中。

由于生成的复制构造函数仅执行浅成员复制,因此它不会分配新的元素数组,因此会出现错误。

You have not defined a copy constructor, so the compiler will generate one for you. This constructor will be called in order to copy the return value of operator*(const & Matrix a) into the result.

As the generated copy constructor only performs a shallow memberwise copy, it will not allocate a new array of elements, hence the error.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文