C++重载+运算符返回类对象时出现pointer being freed错误
问题:C++自定义Matrix类重载+运算符时内存错误
错误信息
a.out(48371,0x10374a600) malloc: *** error for object 0x7ff7bf6525a0: pointer being freed was not allocated a.out(48371,0x10374a600) malloc: *** set a breakpoint in malloc_error_break to debug Abort trap: 6
类定义(.h文件)
class Matrix{ public: Matrix(int); Matrix(); ~Matrix(); int getLength(); float* getData(); void readMatrix(string fileName); Matrix operator + (Matrix &trixIn) { Matrix matrix; float out1[trixIn.getLength()]; float* dataA = trixIn.getData(); float* dataB = data; for (int i = 0; i < trixIn.getLength(); i++){ out1[i] = dataA[i] + dataB[i]; } matrix.length = trixIn.getLength(); matrix.data = out1; // all this data up this point is correct when printed to the terminal return matrix; // returning this to the main function brings up the error } void print(); private: float *data; int length; };
主函数调用代码
Matrix C = A + B; cout << "A + B with overload" << endl; C.print();
print()函数实现
void Matrix::print(){ for (int i = 0; i < length; i++){ cout << std::setw(8) << data[i]; } printf("\n"); }
疑问
报错提示释放未分配的指针,但并未手动尝试释放任何内存,请问该错误含义是什么?如何解决?刚从C转C++,对指针和内存分配不太熟悉,恳请指导。
错误原因与解决方案
错误含义
这个错误的核心是:你给Matrix对象的data指针赋值了栈上的局部数组out1。当operator+函数执行完毕后,栈上的局部变量out1会被系统自动销毁、内存回收。而Matrix的析构函数(~Matrix())大概率在尝试用delete[]释放data指针指向的内存,但out1是栈内存,不是用new分配的堆内存,因此触发“释放未分配指针”的错误。
解决步骤
1. 修正operator+的内存分配方式
把栈数组out1改成用new在堆上分配内存,这样内存不会随函数结束被销毁,且能被析构函数合法释放:
Matrix operator + (Matrix &trixIn) { Matrix matrix; int len = trixIn.getLength(); // 用new在堆上分配内存 float* out1 = new float[len]; float* dataA = trixIn.getData(); float* dataB = data; for (int i = 0; i < len; i++){ out1[i] = dataA[i] + dataB[i]; } matrix.length = len; matrix.data = out1; return matrix; }
2. 确保析构函数正确释放内存
你的~Matrix()需要实现为释放data指针的堆内存,同时处理data为空的情况:
Matrix::~Matrix() { if (data != nullptr) { delete[] data; data = nullptr; } }
3. 修复默认构造函数的初始化问题
默认构造函数要把data初始化为nullptr、length初始化为0,避免野指针:
Matrix::Matrix() : data(nullptr), length(0) {}
4. 补充拷贝构造函数和赋值运算符(Rule of Three)
因为类管理了堆内存,必须实现这两个函数,否则对象拷贝(比如Matrix C = A + B;)会出现浅拷贝,导致多个对象指向同一块堆内存,析构时重复释放:
- 拷贝构造函数:
Matrix::Matrix(const Matrix& other) { length = other.length; if (length > 0) { data = new float[length]; for (int i = 0; i < length; i++) { data[i] = other.data[i]; } } else { data = nullptr; } }
- 赋值运算符:
Matrix& Matrix::operator=(const Matrix& other) { if (this == &other) { return *this; // 防止自赋值 } // 先释放当前对象的内存 if (data != nullptr) { delete[] data; } // 拷贝新数据 length = other.length; if (length > 0) { data = new float[length]; for (int i = 0; i < length; i++) { data[i] = other.data[i]; } } else { data = nullptr; } return *this; }
额外建议
尽量避免手动管理内存,C++中可以用std::vector<float>代替float*,容器会自动处理内存,无需自己写析构、拷贝构造和赋值运算符,代码更安全简洁:
把类中的float* data;改成std::vector<float> data;,int length;可以去掉,用data.size()获取长度,operator+可简化为:
Matrix operator + (Matrix &trixIn) { Matrix matrix; int len = trixIn.data.size(); matrix.data.resize(len); for (int i = 0; i < len; i++){ matrix.data[i] = trixIn.data[i] + this->data[i]; } return matrix; }
内容的提问来源于stack exchange,提问作者koyo
相关产品推荐
相关产品推荐

