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变成悬垂指针,后续访问会读取到垃圾值,甚至触发崩溃。
典型场景:
matrix_creator返回局部对象m时,默认拷贝构造函数复制arr地址,局部对象销毁后释放内存,m1的arr指向已释放空间。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
相关产品推荐
相关产品推荐

