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

C++指针重复删除问题:如何让Canvas类释放指针所有权(不修改main)

解决方案:让Canvas类放弃指针所有权,由main负责清理

问题根源

你的代码中,Canvas::Add方法将传入的原始指针包装成std::unique_ptr,把指针的所有权转移给了Canvas类。当m_canvasItems中的unique_ptr被销毁(比如Canvas对象析构、vector元素被清除)时,会自动调用delete释放指针。而main函数中又手动调用delete,导致同一指针被两次释放,触发内存错误。

可行方案

由于无法修改main.cpp的逻辑,你需要让Canvas类只保存指针的引用,不获取所有权。有两种合理的实现方式:

方案1:修改Canvas的存储类型(推荐)

将m_canvasItems的类型从std::vector<std::unique_ptr<CanvasItem>>改为std::vector<CanvasItem*>,让Canvas仅保存原始指针,不管理其生命周期:

// Canvas类的成员变量修改
std::vector<CanvasItem*> m_canvasItems;

// 修改Add方法
void Canvas::Add(CanvasItem* item) {
    m_canvasItems.push_back(item); // 仅存储指针,不转移所有权
}

同时确保Canvas的析构函数不会删除这些指针(默认析构函数就不会,无需额外操作)。这样main函数中手动delete指针时,不会和Canvas的操作冲突。

方案2:利用std::unique_ptr::release(仅当无法修改存储类型时使用)

如果因为代码依赖无法修改m_canvasItems的类型,你可以在Add方法中创建unique_ptr后立刻调用release(),放弃对指针的所有权:

void Canvas::Add(CanvasItem* item) {
    std::unique_ptr<CanvasItem> ptr(item);
    m_canvasItems.push_back(std::move(ptr));
    // 释放所有权,让unique_ptr不再管理该指针
    m_canvasItems.back().release();
}

注意:这种方式下,m_canvasItems中的unique_ptr会变成空指针,如果你需要通过Canvas访问这些CanvasItem对象,还需要额外存储原始指针(比如再维护一个vector<CanvasItem*>),因此方案1是更简洁的选择。

关键说明

std::unique_ptr::release的作用正是释放智能指针对原始指针的所有权,返回原始指针且不触发删除操作,完全符合你需要让main接管所有权的需求。但只有在无法修改存储类型的场景下,才推荐用这种方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:16:03