C++ 程序崩溃在:(1)矩阵乘法;(2)矩阵加减失败

C++ 程序崩溃在:(1)矩阵乘法;(2)矩阵加减失败,c++,multidimensional-array,matrix-multiplication,dynamic-memory-allocation,C++,Multidimensional Array,Matrix Multiplication,Dynamic Memory Allocation,简而言之,我的任务是创建一个动态分配内存以形成int值矩阵的类 类的一部分是执行基本矩阵计算(加法、减法和乘法)的成员函数。一切都可以编译(至少在我这方面),但当我使用驱动程序测试乘法部分时,它总是崩溃 我使用代码块作为我的IDE,但在尝试找出它时,调试器并没有给我带来太多的运气。计算似乎完成了(使用正确的值),但随后某个地方出现了可怕的错误 为清楚起见,矩阵类的每个对象都有以下成员数据: private: int rows; int cols; int **elemen

简而言之,我的任务是创建一个动态分配内存以形成int值矩阵的类

类的一部分是执行基本矩阵计算(加法、减法和乘法)的成员函数。一切都可以编译(至少在我这方面),但当我使用驱动程序测试乘法部分时,它总是崩溃

我使用代码块作为我的IDE,但在尝试找出它时,调试器并没有给我带来太多的运气。计算似乎完成了(使用正确的值),但随后某个地方出现了可怕的错误

为清楚起见,矩阵类的每个对象都有以下成员数据:

private:
    int rows;
    int cols;
    int **element;
下面是实现文件的一个片段,其中重载运算符*得到充实。在执行乘法的循环被注释掉之前,temp.element[i][x]被设置为“0”的部分,因为默认构造函数已经将所有值设置为“0”——我最初将其放入时忘记了这一点。当我没有把它注释掉的时候,它也不起作用

在测试中,我使用了一个2x3阵列和一个3x2阵列

Matrix Matrix::operator*(const Matrix &aMatrix) const
{
    if(cols == aMatrix.rows)
    {
        Matrix temp(rows, aMatrix.cols);
        for(int i = 0; i < rows; i++)
        {
            for(int x = 0; x < aMatrix.cols; x++)
            {
                //temp.element[i][x] = 0;
                for(int n = 0; n < cols; n++)
                {
                    temp.element[i][x] += (element[i][n]
                                       * aMatrix.element[n][x]);
                }
            }
        }
        return temp;
    }
    else
    {
        cerr << "Matrix multiplication failed -- incompatible matrix sizes."
             << endl;
        return *this;
    }
}
矩阵::运算符*(常数矩阵和aMatrix)常数
{
if(cols==aMatrix.rows)
{
矩阵温度(行、aMatrix.cols);
对于(int i=0;icerr您需要弄清楚这些操作的语法和语义是什么。从您的示例来看,似乎您需要如下内容:

Matrix lhs = <something>;
Matrix rhs = <something>;
Matrix result = lhs * rhs;
矩阵lhs=;
矩阵rhs=;
矩阵结果=lhs*rhs;
“只工作”。虽然这在语法上可能很好,但您需要考虑如果lhs和rhs不能相乘(或添加,等等)会发生什么情况。您还需要担心结果设置是否正确。您不能只返回“由行数、列数和指针数组组成的结构”希望不会遇到可怕的内存管理问题

<>什么使产品消失?当它超出范围时?C++不是线性代数的一个很好的语言。< / P> 您需要做的第一个决定是,是否打算为无效操作抛出异常,或者向错误消息返回一些错误指示,可能是bool和const char*

然后,您可能应该尝试编写一个函数,其中包含一个结果引用和两个操作数引用,如果矩阵支持该操作,则只需正确处理基本代数即可。(我还没有提到,您的矩阵仅为整数矩阵。)

在“现实生活”中,您可能会试图找到一个管理所有这些的开源标准解决方案,因为数字操作需要非常小心地管理


甚至有人可能会说,这是一个几十年前用Fortran已经很好地解决了的问题,到今天,如果性能是一个问题,那么底层计算很有可能在Fortran中,或者是一个库,它是C的一个端口。

您发布了一个复制构造函数和赋值操作符。Your分配操作员有4个主要问题:

  • 您应该通过常量引用传递参数,而不是通过值传递参数
  • 您应该返回对当前对象的引用,而不是一个全新的对象
  • 如果
    new
    在赋值过程中抛出异常,则表示您事先删除了内存,从而将对象弄乱了
  • 它是多余的。相同的代码出现在复制构造函数中
  • 您可以根据复制构造函数重写赋值运算符,并缓解这些问题:

    #include <algorithm>
    //...
    Matrix& Matrix::operator=(const Matrix& aMatrix)
    {
        Matrix temp(aMatrix);
        swap(*this, temp);
        return *this;
    }
    
    void Matrix::swap(Matrix& left, Matrix& right)
    {
       std::swap(left.rows, right.rows);
       std::swap(left.cols, right.cols);
       std::swap(left.element, right.element);
    }
    

    因此,如果矩阵大小是一个问题,运算符+和+=将抛出一个异常。请注意运算符
    +
    是如何根据
    +=
    实现的。对
    *
    *=
    、以及
    -
    -=

    元素
    如何分配内存?是否应该检查f或者在做任何算术之前的维度?它是在默认构造函数中动态分配的。我用动态内存分配标记了这个问题,但没有包括>.<--不想让它陷入太多的代码。更具体地说,它默认为0x0,但接受两个参数分别定义行和列。@uber08-您正在按值返回一个矩阵。这意味着我们需要查看您的
    Matrix
    用户定义的复制构造函数、赋值运算符和析构函数。它们在您发布的代码中都扮演着重要角色。@uber08-
    Matrix Matrix::operator=(Matrix aMatrix)
    您应该按常量引用传递,而不是按值传递。此外,您应该返回一个引用,而不是一个全新的对象。它有很多错误,并且会导致问题。我无法想象有什么好的理由在出现错误的情况下返回操作的lhs。客户端代码可能注定会出现各种计算错误ns和关于标准错误的相应错误消息。作为一个实际问题,假设库拥有标准错误对客户端的开发人员来说可能是痛苦的。也许他们对标准错误有特定的想法。也许他们将其重定向到了类似/dev/null的位置。感谢您仔细查看。我一直在为发生了什么而苦苦挣扎一旦函数被调用,就只有这个玲珑的产品了……不幸的是,我被提供给我们的原型束缚在这个结构上。我会考虑你的其他建议。@uber08-正如上面的评论所述,你需要首先确保你的
    Matrix::Matrix(const Matrix &aMatrix)
    {
        rows = aMatrix.rows;
        cols = aMatrix.cols;
        element = new int* [rows];
        for(int i = 0; i < rows; i++)
        {
            element[i] = new int [cols];
            for (int x = 0; x < cols; x++)
            {
                element[i][x] = aMatrix.element[i][x];
            }
        }
    }
    
    Matrix::~Matrix()
    {
        for(int i = 0; i < rows; i++)
        {
            delete [] element[i];
            element[i] = NULL:
        }
        delete [] element;
        element = NULL;
    }
    
    Matrix lhs = <something>;
    Matrix rhs = <something>;
    Matrix result = lhs * rhs;
    
    #include <algorithm>
    //...
    Matrix& Matrix::operator=(const Matrix& aMatrix)
    {
        Matrix temp(aMatrix);
        swap(*this, temp);
        return *this;
    }
    
    void Matrix::swap(Matrix& left, Matrix& right)
    {
       std::swap(left.rows, right.rows);
       std::swap(left.cols, right.cols);
       std::swap(left.element, right.element);
    }
    
    Matrix& Matrix::operator+=(const Matrix &aMatrix)
    {
        if(rows != aMatrix.rows || cols != aMatrix.cols)
           throw SomeException;
        for(int i = 0; i < rows; i++)
        {
            for(int x = 0; x < cols; x++)
                element[i][x] += aMatrix.element[i][x];
        }
        return *this;
    }
    
    Matrix Matrix::operator+(const Matrix &aMatrix)
    {
       Matrix temp(*this);
       temp += aMatrix;
       return temp;
    }