You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将transpose()方法生成的转置矩阵赋值给原Matrix对象?

如何将transpose()方法生成的转置矩阵赋值给原Matrix对象?

嘿,我仔细看了你的代码,发现问题主要出在三个地方:一是你没接收transpose()返回的转置矩阵并赋值给原对象,二是你的拷贝构造和赋值运算符是浅拷贝,会导致严重内存错误,还有数组索引越界的bug。咱们一步步解决:

1. 先修复致命的浅拷贝问题

你的werte是指向指针数组的指针,直接让werte = M.werte会让两个Matrix对象共享同一块内存,析构时会重复释放同一块内存导致崩溃,必须实现深拷贝

  • 修改拷贝构造函数:
Matrix::Matrix(const Matrix& M) // 深拷贝构造
{
    Zeile = M.Zeile;
    Spalte = M.Spalte;
    // 先分配行内存
    werte = new double*[Zeile];
    for (int r = 0; r < Zeile; r++)
    {
        // 分配每行的列内存
        werte[r] = new double[Spalte];
        // 逐个拷贝元素
        for (int c = 0; c < Spalte; c++)
        {
            werte[r][c] = M.werte[r][c];
        }
    }
}
  • 修改赋值运算符,还要处理自赋值避免误删内存:
Matrix& Matrix::operator= (const Matrix& M) // 返回引用更高效
{
    // 自赋值直接返回,避免释放自己的内存
    if (this == &M)
        return *this;
    
    // 先释放原对象的旧内存
    for (int r = 0; r < Zeile; r++)
    {
        delete[] werte[r];
    }
    delete[] werte;
    
    // 重新分配内存并拷贝元素
    Zeile = M.Zeile;
    Spalte = M.Spalte;
    werte = new double*[Zeile];
    for (int r = 0; r < Zeile; r++)
    {
        werte[r] = new double[Spalte];
        for (int c = 0; c < Spalte; c++)
        {
            werte[r][c] = M.werte[r][c];
        }
    }
    return *this;
}

2. 修复数组索引越界bug

你代码里多处用r-1c-1当索引,r=0时会变成负数直接越界,咱们统一用C++默认的0-based索引,如果要支持1-based的外部调用,在方法内部转换:

  • 修改构造函数:
Matrix::Matrix(int zeilen, int spalten)
{
    this->Zeile = zeilen;
    this->Spalte = spalten;
    // 行的数量是Zeile,所以分配Zeile个指针
    werte = new double*[Zeile];
    for (int r = 0; r < Zeile; r++)
    {
        werte[r] = new double[Spalte];
    }
    
    double init_mit = 0;
    for (int r = 0; r < Zeile; r++)
    {
        for (int c = 0; c < Spalte; c++)
        {
            werte[r][c] = init_mit;
            cout << werte[r][c] << "\t";
        }
        cout << endl;
    }
}
  • 修改setze_element方法(支持1-based参数):
int Matrix::setze_element(int zeile, int spalte, double Wert_setzen)
{
    // 1-based转0-based,先判断是否在合法范围
    if (zeile >= 1 && zeile <= Zeile && spalte >= 1 && spalte <= Spalte)
    {
        werte[zeile - 1][spalte - 1] = Wert_setzen;
        return 1;
    }
    else
    {
        cout << "Wert Ausserhalb der Matrix. Abbruch!" << endl;
        return 0;
    }
}
  • 修改transpose和输出运算符的索引:
Matrix Matrix::transpos()
{
    int MT_zeile = Spalte;
    int MT_spalte = Zeile;
    cout << "Shows transpose Matrix by default." << endl;
    
    Matrix MT(MT_zeile, MT_spalte);
    for (int r = 0; r < Zeile; r++)
    {
        for (int c = 0; c < Spalte; c++)
        {
            // 转置逻辑:原[r][c] → 新[c][r]
            MT.werte[c][r] = werte[r][c];
        }
    }
    return MT;
}

ostream& operator << (ostream& stream, Matrix& m)
{
    for (int r = 0; r < m.Zeile; r++) {
        for (int c = 0; c < m.Spalte; c++)
        {
            stream << m.werte[r][c] << "\t";
        }
        stream << endl;
    }
    return stream;
}

3. 正确赋值转置矩阵给原对象

你原来调用M.transpos()但没接收返回值,原对象不会变化,只需要把返回的转置矩阵赋值给M即可:

int main()
{
    Matrix M(5, 3); // 初始化5行3列矩阵
    cout << endl;
    
    cout << "Transpose starts here." << endl;
    M.setze_element(1, 3, 5); // 设置第1行第3列的值为5(1-based)
    cout << "Element is set to value 5." << endl;
    cout << M << endl;
    
    // 把转置后的矩阵赋值给原对象M
    M = M.transpos();
    
    cout << "Now should show the transpose matrix with the object values." << endl;
    cout << M; // 现在输出的就是转置后的矩阵了
    cout << endl;
    
    return 0;
}

补充:修复析构函数避免内存泄漏

原来的空析构函数会导致内存泄漏,必须释放分配的内存:

Matrix::~Matrix()
{
    for (int r = 0; r < Zeile; r++)
    {
        delete[] werte[r];
    }
    delete[] werte;
}

这样修改后,程序就能正确把转置矩阵赋值给原对象,同时避免所有内存问题啦!

备注:内容来源于stack exchange,提问作者Eric

火山引擎 最新活动