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

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();
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 00:09:23