如何解决C++使用Simple2D库时delete[]触发断点的问题?
执行
delete [] coor触发断点异常的原因及解决方法 问题核心原因:重复释放内存(Double Free)
你的代码存在浅拷贝导致的重复内存释放问题,具体流程如下:
- 在
update函数中创建Axis ax1对象,构造函数通过new float[n_points]给coor分配了堆内存。 - 调用
drawAxis(ax1)时,因为函数参数是Axis axis(传值传递),会触发C++默认的拷贝构造函数,创建ax1的副本。默认拷贝构造是浅拷贝,直接复制指针值,导致副本的coor和ax1的coor指向同一块堆内存。 drawAxis函数执行完毕后,局部的axis副本被销毁,调用~Axis()释放了coor指向的内存。- 当
update函数执行完毕,ax1对象也被销毁,再次调用~Axis(),此时coor已经是野指针(指向的内存已被释放),再次执行delete[] coor就会触发重复释放内存的断点异常。
解决方案
方案1:使用引用传递避免对象拷贝
修改drawAxis的参数为引用类型,这样不会创建对象副本,也就不会出现两次释放同一块内存的情况:
void drawAxis(Axis& axis) // 将参数改为引用 { S2D_DrawLine(0, 300, 800, 300, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1); }
方案2:实现深拷贝的拷贝构造函数与赋值运算符
为Axis类自定义拷贝构造函数和赋值运算符,在拷贝时重新分配内存并复制数据(深拷贝),让原对象和拷贝对象的coor指向不同的内存块:
class Axis { // ... 原有成员 ... public: // 拷贝构造函数:深拷贝 Axis(const Axis& other) { name = other.name; start = other.start; end = other.end; n_points = other.n_points; width = other.width; // 重新分配内存并复制数据 coor = new float[n_points]; for (int i = 0; i < n_points; ++i) { coor[i] = other.coor[i]; } } // 赋值运算符重载(遵循拷贝交换 idiom) Axis& operator=(Axis other) { std::swap(name, other.name); std::swap(start, other.start); std::swap(end, other.end); std::swap(n_points, other.n_points); std::swap(width, other.width); std::swap(coor, other.coor); return *this; } // ... 原有构造、析构函数 ... };
方案3:使用智能指针自动管理内存
用std::unique_ptr<float[]>替换原始指针,智能指针会自动管理内存释放,同时unique_ptr禁止拷贝,从根源上避免浅拷贝问题:
#include <memory> // 需要包含智能指针头文件 class Axis { friend class Window; std::unique_ptr<float[]> coor; // 替换原始指针 int n_points; float start, end, width; char name; void calculatePoints() { float scale = (end - start) / n_points; for (int i = 0; i < n_points; i++) { coor[i] = start + (scale * i); // 直接用[]访问 } } public: Axis(char n='X', float st=-100, float e=100, int points = 10, int w = 3) { if (st < e) { name = n; start = st; end = e; n_points = points; width = w; coor = std::make_unique<float[]>(n_points); // 自动分配内存 calculatePoints(); } else { std::cout << "Invalid data! Start cannot be of a larger value than end!"; } } ~Axis() { // 无需手动delete,智能指针会在对象销毁时自动释放内存 } };
内容的提问来源于stack exchange,提问作者mxon9
相关产品推荐
相关产品推荐

