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

基础数据类型赋值运算符与临时对象:C++悬空指针疑问问询

你的unique_ptr悬空指针疑问拆解

嘿,这个问题挺典型的,咱们一步步把它说透!首先得给你拍板:你最初的判断是对的——puter确实是悬空指针,你运行时没出问题只是撞上了C++里的「未定义行为」,这可不是代码没问题哦!

先给你捋清楚底层到底发生了什么:

  • 当你调用std::make_unique<int>(50)时,程序会在堆上开辟一块内存存50,同时返回一个临时的unique_ptr<int>对象——这个临时对象是这块堆内存的「唯一主人」,负责最后销毁它。
  • 你调用.get()的时候,只是从这个临时unique_ptr手里拿到了它内部存的裸指针,但完全没拿走所有权——临时unique_ptr还是牢牢握着这块内存的处置权。
  • 关键来了:C++里的临时对象,生命周期只到「包含它的完整表达式结束」为止。这里的完整表达式就是puter = std::make_unique<int>(50).get();这整行语句。等这行代码执行完,那个临时unique_ptr就会被销毁,它的析构函数会立刻把手里的堆内存给释放掉。
  • 这时候puter存的裸指针,就指向了一块已经被操作系统回收的内存——也就是咱们说的悬空指针。之后你解引用*puter的行为属于「未定义行为」:有时候碰巧内存还没被覆盖,你能读到原来的50;有时候直接崩溃;甚至可能出现更诡异的结果,完全看运气和运行环境,绝对不能依赖。

你之前猜是不是「unique_ptr的资源被移动赋值给了puter」,其实不对——puter是个裸指针,unique_ptr的所有权转移只发生在unique_ptr对象之间,裸指针接不住这个所有权。如果想安全地用这块内存,你应该把puter声明成std::unique_ptr<int>类型,直接赋值:

std::unique_ptr<int> puter = std::make_unique<int>(50);
if(puter) {
    std::cout << *puter << std::endl;
}

这样puter就成了这块内存的新主人,直到它自己被销毁时才会释放内存,完全安全。

说白了,你的代码本质上是有问题的,运行时没报错只是运气好,这种写法绝对不能出现在生产代码里哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:50:07