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

C++新手求教:unique_ptr调用get()两种写法为何结果不同?

为什么从临时unique_ptr获取的裸指针会失效?

嘿,这个问题问得太到位了,刚好踩中了std::unique_ptr最容易被新手忽略的生命周期陷阱!咱们一步步拆解两种写法的本质区别:

第一种写法:从临时unique_ptr拿裸指针

auto w = (std::make_unique<Wall>()).get();

这里std::make_unique<Wall>()创建的是一个没有名字的临时unique_ptr对象。C++里临时对象的生命周期非常短——它只存在于当前这条语句执行期间,等到分号;一出现,这个临时unique_ptr就会被立刻销毁。

而unique_ptr的核心职责就是管理对象的生命周期:当它被销毁时,会自动调用delete释放它持有的内存。所以这条语句执行完,w虽然拿到了一个非空的裸指针,但它指向的Wall对象已经被临时unique_ptr销毁了!

这时候你做空值检查,w的地址确实不是nullptr(因为之前get()返回的是有效的内存地址),但那块内存已经被归还给系统了。后续使用w的时候,要么是读取已经释放的内存(无效读取),如果你的代码里还尝试手动delete w,就会触发Valgrind报的“双重删除”——因为Wall已经被临时unique_ptr删过一次了。

第二种写法:从命名unique_ptr拿裸指针

auto wall = std::make_unique<Wall>(); 
auto w = wall.get();

这里的wall是一个命名的unique_ptr变量,它的生命周期和普通变量一样:从定义的位置开始,直到它所在的作用域结束(比如函数执行完毕,或者它被手动销毁)。只要wall还活着,它就会牢牢持有Wall对象的所有权,不会自动释放内存。

所以w作为裸指针指向的是wall管理的有效内存,只要wall没被销毁,w就能安全使用(当然,你得保证不会在wall销毁后继续用w,那又是另一个悬空指针问题了)。

核心总结

  • 永远不要从临时智能指针中获取裸指针,因为临时对象的生命周期太短,会立刻释放内存,导致裸指针变成悬空指针。
  • unique_ptr的核心是所有权管理,命名的智能指针会在作用域内维持对象的生命周期,而临时智能指针只会活过当前语句。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:30:16