Data类代码经Valgrind检测存在确定内存泄漏,求排查原因
Data类内存泄漏问题分析
核心泄漏原因:析构函数未释放外层指针数组
你的Data类构造函数中为data分配了两层内存:
- 外层:
this->data = new float*[r];(存储行指针的数组) - 内层:
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
相关产品推荐
相关产品推荐

