C++动态内存程序问题:多边形类代码存在内存泄漏求助
Polygon类内存泄漏问题排查与解决方案
问题描述
我正在编写一个为Polygon类添加点的C++程序,代码如下。程序出现内存泄漏问题,完全无从下手,恳请帮助!
UPDATE: 是否存在memcpy的替代方案?
原始代码
#include <iostream> #include <cstring> #include <cstdint> struct Coordinate { int x, y; Coordinate () : x(), y() {} Coordinate (int _x, int _y) : x(_x), y(_y) {} }; class Polygon { int points; Coordinate** coordinates; public: Polygon (int _points) { points = _points; coordinates = new Coordinate*[points+1]; } ~Polygon () { for (int i = 0; i <=points; i++){ delete coordinates[i]; } delete [] coordinates; } void putPoint (Coordinate ** pts) { for (int i = 0; i < points; i++) { memcpy(&coordinates[i], &pts[i%points], sizeof(coordinates[i])); } } }; int main () { Coordinate q1 = {0,0}; Coordinate q2 = {0,2}; Coordinate q3 = {2,2}; Coordinate q4 = {2,0}; Coordinate* quadPts[4] = {&q1, &q2, &q3, &q4}; Polygon * quad = new Polygon(4); quad->putPoint(quadPts); }
错误信息
20066ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7fd18ba55947 in operator new(unsigned long) (/lib/x86_64-linux-gnu/libasan.so.5+0x10f947)
Indirect leak of 32 byte(s) in 1 object(s) allocated from:
#0 0x7fd18ba55b47 in operator new[](unsigned long) (/lib/x86_64-linux-gnu/libasan.so.5+0x10fb47)
问题根源
- 未销毁Polygon对象:main函数中用
new创建了Polygon实例,但未调用delete销毁它,导致Polygon的析构函数从未执行,内部的coordinates指针数组无法被释放,这是内存泄漏的直接原因。 - 指针管理错误:
coordinates是二级指针,构造函数仅分配了指针数组,但未为每个指针分配对应的Coordinate对象;putPoint中通过memcpy将栈上对象的地址复制到指针数组,析构时delete栈上对象的地址会触发未定义行为。- 构造函数分配了
points+1个指针,但putPoint仅初始化了前points个,最后一个指针是野指针,析构时delete野指针同样会引发未定义行为。
- 不必要的memcpy:用
memcpy复制指针完全多余,C++中直接赋值指针或对象即可。
解决方案
修复内存泄漏与指针问题
推荐简化类的内存管理,直接存储Coordinate对象数组(而非二级指针),避免复杂的指针操作:
#include <iostream> #include <cstdint> struct Coordinate { int x, y; Coordinate() : x(), y() {} Coordinate(int _x, int _y) : x(_x), y(_y) {} }; class Polygon { int points; Coordinate* coordinates; // 一维对象数组,简化内存管理 public: Polygon(int _points) : points(_points) { coordinates = new Coordinate[points]; // 分配points个Coordinate对象 } ~Polygon() { delete[] coordinates; // 直接释放对象数组 } void putPoint(Coordinate* pts) { for (int i = 0; i < points; i++) { coordinates[i] = pts[i % points]; // 直接赋值对象,替代memcpy } } }; int main() { Coordinate q1 = {0,0}; Coordinate q2 = {0,2}; Coordinate q3 = {2,2}; Coordinate q4 = {2,0}; Coordinate quadPts[4] = {q1, q2, q3, q4}; // 存储对象副本 Polygon* quad = new Polygon(4); quad->putPoint(quadPts); delete quad; // 销毁Polygon对象,释放内部资源 }
memcpy的替代方案
完全不需要使用memcpy:
- 如果存储对象:直接用
=赋值Coordinate对象(如上述代码所示),C++会自动调用默认的拷贝构造函数完成对象复制。 - 如果坚持使用指针:直接赋值指针即可(但需确保指针指向合法的堆内存,避免悬空指针),例如:
coordinates[i] = pts[i % points]; // 直接复制指针值
额外说明
如果必须使用二级指针,需确保每个指针指向堆上分配的Coordinate对象,同时修正构造/析构逻辑:
// 构造函数修改为分配points个指针 Polygon(int _points) : points(_points) { coordinates = new Coordinate*[points]; } // putPoint中为每个指针分配堆对象 void putPoint(Coordinate** pts) { for (int i = 0; i < points; i++) { coordinates[i] = new Coordinate(*pts[i % points]); // 复制栈对象到堆上 } } // 析构函数循环到points(而非points+1) ~Polygon() { for (int i = 0; i < points; i++){ delete coordinates[i]; } delete[] coordinates; }
内容的提问来源于stack exchange,提问作者artemis122353
相关产品推荐
相关产品推荐

