You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++矩阵类加法返回垃圾值,寻求代码错误排查帮助

矩阵加法返回垃圾值问题排查

我编写了一个可处理不同维度整数矩阵的C++ Matrix类,重载了加法、比较运算符,目标是实现矩阵加法返回两矩阵的和,但实际运行返回垃圾值。需求是编写支持不同维度整数矩阵的类,重载加法、乘法与比较运算符。多次检查代码未找到错误,附上代码及运行现象,请求排查。

问题代码

#include <iostream>
using namespace std;

class Matrix
{
    int rows, cols;
    int * arr;
    public:
        Matrix(int rows, int cols) : rows(rows), cols(cols) 
        {
            arr = new int[rows * cols];
        }

        void insert()
        {
            cout << "Enter the values of matrix from position [00] to ["<< rows << cols <<"], seprated with space : " << endl;
            for(int i = 0; i < rows * cols; i++)
                cin >> arr[i];
        }

        void retrieve()
        {
            cout << "The Matrix stored is : " << endl;
            for(int i = 0; i < rows * cols; i++)
            {
                cout << " " << arr[i] << " ";
                if((i + 1) % cols == 0) cout << endl;
            }
        }

        bool operator==(Matrix other)
        {
            if(rows != other.rows || cols != other.cols)
                return false;

            for(int i = 0; i < rows * cols; i++)
            {
                if(arr[i] != other.arr[i])
                    return false;
            }
            return true;
        }

        Matrix operator+(Matrix other)
        {
            if(rows != other.rows || cols != other.cols)
            {
                cout << "Number of Row(s)/Column(s) unequal!" << endl <<"Addition not Possible.";
                return Matrix(0,0);
            }
            else
            {
                Matrix sum(rows, cols);
                for(int i = 0; i < rows * cols; i++)
                    sum.arr[i] =  arr[i] + other.arr[i];

                return sum;
            }
        }

        ~Matrix()
        {
            delete [] arr;
        }
};

Matrix matrix_creator()
{
    int rows, columns;

    cout << "Enter the number of Rows and Columns in the matrix, respectively : " << endl;
    cin >> rows >> columns;

    Matrix m(rows, columns);
    m.insert();
    m.retrieve();

    return m;
}

int main()
{
    Matrix m1 = matrix_creator();
    Matrix m2 = matrix_creator();

    cout << "Matrix Addition Result:" << endl;
    (m1 + m2).retrieve();

    if (m1 == m2) {
        cout << "Matrices are equal." << endl;
    } else {
        cout << "Matrices are not equal." << endl;
    }

    return 0;
}

问题根源:浅拷贝导致的悬垂指针

代码未显式定义拷贝构造函数和赋值运算符重载,C++自动生成的默认拷贝是浅拷贝:

  • 仅复制rows、cols和指针arr的内存地址,不会重新分配内存复制数组内容。
  • 当临时对象(如函数返回的局部对象、运算符返回的对象)销毁时,析构函数会释放arr指向的内存,此时原对象的arr变成悬垂指针,后续访问会读取到垃圾值,甚至触发崩溃。

典型场景:

  1. matrix_creator返回局部对象m时,默认拷贝构造函数复制arr地址,局部对象销毁后释放内存,m1的arr指向已释放空间。
  2. operator+返回sum时,临时对象拷贝后销毁,调用retrieve时访问的是已释放内存,出现垃圾值。

修复方案

1. 实现深拷贝的拷贝构造函数

Matrix(const Matrix& other) : rows(other.rows), cols(other.cols) {
    arr = new int[rows * cols];
    for(int i = 0; i < rows * cols; ++i) {
        arr[i] = other.arr[i];
    }
}

2. 重载赋值运算符(拷贝并交换惯用法)

Matrix& operator=(Matrix other) {
    swap(rows, other.rows);
    swap(cols, other.cols);
    swap(arr, other.arr);
    return *this;
}

按值传参自动调用拷贝构造生成临时对象,交换后临时对象销毁时带走旧内存,无需手动释放,同时避免自我赋值问题。

3. 优化运算符参数传递

将operator+和operator==的参数改为const引用,避免不必要拷贝,同时保证不修改传入对象:

bool operator==(const Matrix& other) const {
    if(rows != other.rows || cols != other.cols)
        return false;

    for(int i = 0; i < rows * cols; ++i) {
        if(arr[i] != other.arr[i])
            return false;
    }
    return true;
}

Matrix operator+(const Matrix& other) const {
    if(rows != other.rows || cols != other.cols) {
        cout << "Number of Row(s)/Column(s) unequal!" << endl << "Addition not Possible.";
        return Matrix(0,0);
    } else {
        Matrix sum(rows, cols);
        for(int i = 0; i < rows * cols; ++i) {
            sum.arr[i] = arr[i] + other.arr[i];
        }
        return sum;
    }
}

可选:添加移动构造与移动赋值(C++11+)

提升临时对象转移的性能,避免深拷贝:

Matrix(Matrix&& other) noexcept : rows(other.rows), cols(other.cols), arr(other.arr) {
    other.rows = 0;
    other.cols = 0;
    other.arr = nullptr;
}

Matrix& operator=(Matrix&& other) noexcept {
    if(this != &other) {
        delete[] arr;
        rows = other.rows;
        cols = other.cols;
        arr = other.arr;
        other.rows = 0;
        other.cols = 0;
        other.arr = nullptr;
    }
    return *this;
}

内容的提问来源于stack exchange,提问作者ARSH PATHAK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:52:09