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

如何解决C++使用Simple2D库时delete[]触发断点的问题?

执行delete [] coor触发断点异常的原因及解决方法

问题核心原因:重复释放内存(Double Free)

你的代码存在浅拷贝导致的重复内存释放问题,具体流程如下:

  1. 在update函数中创建Axis ax1对象,构造函数通过new float[n_points]给coor分配了堆内存。
  2. 调用drawAxis(ax1)时,因为函数参数是Axis axis(传值传递),会触发C++默认的拷贝构造函数,创建ax1的副本。默认拷贝构造是浅拷贝,直接复制指针值,导致副本的coor和ax1的coor指向同一块堆内存。
  3. drawAxis函数执行完毕后,局部的axis副本被销毁,调用~Axis()释放了coor指向的内存。
  4. 当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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 02:27:02