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

能否将栈/全局变量传入接受std::shared_ptr的函数?自定义实现是否有风险?

该实现存在多处潜在风险与设计冗余,具体如下:

1. 公有继承std::shared_ptr隐含未定义行为

std::shared_ptr的析构函数不是虚函数,如果代码中出现基类指针指向派生类实例后执行delete的操作,会直接触发未定义行为,派生类部分无法被正确析构。即便你的派生类没有额外成员、当前测试未暴露问题,这也属于违反C++设计规范的实现。
实际上你完全不需要自定义派生类,直接使用std::shared_ptr原生的支持自定义删除器的构造函数即可实现完全相同的效果,没有任何继承必要:

// 原生shared_ptr即可实现无操作删除逻辑,无需自定义派生类
std::shared_ptr<T> stack_ptr(target, [](T* /* unused */) {});

2. 贴出的代码存在语法错误

你给出的示例代码末尾多写了一个多余的};,类定义结束仅需要一组闭合大括号加分号,能正常编译运行应该是实际编写时修正了这个笔误。

3. 使用场景存在隐性未定义行为风险

该实现仅保证了智能指针引用计数归零时不释放目标内存,但没有任何机制约束传入的栈变量/全局变量的生命周期长于所有持有该智能指针的对象。如果接收std::shared_ptr的函数将指针持久化存储,在栈变量弹出销毁、全局变量析构之后再访问指针,就会触发野指针访问,属于典型的未定义行为。

4. 空删除器可能不符合部分场景需求

你当前使用的空删除器不会执行目标对象的析构函数,如果T类型的析构函数包含内存释放之外的逻辑(比如释放文件句柄、归还互斥锁、刷写IO缓冲区等),会导致这部分逻辑丢失,引发资源泄漏。

注意:如果你的场景需要执行析构逻辑但不释放内存(比如目标对象在自定义申请的堆内存上构造),可以将删除器改为[](T* p) { p->~T(); };但该写法绝对不能用于栈/全局变量,否则栈弹出、程序退出时对象析构函数会被二次调用,直接触发未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:27:01