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

Data类代码经Valgrind检测存在确定内存泄漏,求排查原因

Data类内存泄漏问题分析

核心泄漏原因:析构函数未释放外层指针数组

你的Data类构造函数中为data分配了两层内存:

  1. 外层:this->data = new float*[r];(存储行指针的数组)
  2. 内层:this->data[i] = new float[c];(每行的float数据数组)

但析构函数仅释放了内层的每行数据,完全漏掉了释放外层的行指针数组!这直接导致每次Data对象析构时,外层数组的内存永远无法被回收,正好对应Valgrind提示的泄漏块。

修复代码:

Data::~Data(){
    for(int i = 0; i < this->row; i++){
        delete[] this->data[i];
        this->data[i] = nullptr;
    }
    // 新增:释放外层行指针数组
    delete[] this->data;
    this->data = nullptr;
    this->row = 0;
    this->col = 0;
}

潜在风险:缺少深拷贝的拷贝构造与赋值运算符

当前Data类依赖编译器生成的默认拷贝构造和赋值运算符,这两个默认实现是浅拷贝——只会直接复制data指针的值,不会重新分配内存复制数据。这会导致多个Data对象共享同一块内存:

  • 当其中一个对象析构释放内存后,其他对象的data会变成野指针
  • 后续操作野指针会触发崩溃、重复释放等未定义行为

即使本次泄漏不是由此直接导致,也必须修复这个问题:

实现拷贝构造函数(深拷贝)

Data::Data(const Data& other) {
    this->row = other.row;
    this->col = other.col;
    this->data = new float*[row];
    for (int i = 0; i < row; i++) {
        this->data[i] = new float[col];
        memcpy(this->data[i], other.data[i], sizeof(float) * col);
    }
}

实现赋值运算符重载(拷贝交换 idiom)

#include <algorithm> // 需要引入swap头文件

Data& Data::operator=(Data other) {
    std::swap(this->row, other.row);
    std::swap(this->col, other.col);
    std::swap(this->data, other.data);
    return *this;
}

验证修复

完成上述修改后重新编译,用Valgrind扫描即可确认原泄漏提示消失,同时也规避了浅拷贝带来的后续风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 23:32:57