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

C++中指向栈变量的std::shared_ptr行为不符预期,求解析

你的核心误解:std::make_shared不会指向栈变量

第一个实验的问题

你完全搞错了std::make_shared<Rectangle>(r)的本质——它不是让shared_ptr指向栈上的r,而是会在堆内存中创建一个全新的Rectangle对象,然后用栈上的r作为参数(调用拷贝构造函数)初始化这个堆对象。

返回的shared_ptr管理的是这个堆上的拷贝,和栈上的r没有任何关联。栈上的r确实会在函数结束时销毁,但这对堆上的拷贝毫无影响,所以代码正常输出6是完全合理的,根本不存在悬空指针的问题。

裸指针实验的合理性

这个实验才是真正的“返回栈变量指针”:你直接返回了&r,也就是栈上对象的内存地址。函数结束后r被销毁,该地址对应的内存变成无效区域,访问它属于未定义行为——输出垃圾值是这种行为的典型表现(当然未定义行为也可能碰巧输出正确值,只是你这次没遇到)。

第三个实验的逻辑错误

rectPtr管理的依然是堆上的拷贝,它在if块结束时销毁的是堆上的那个对象,和栈上的r无关。后面返回的make_shared<Rectangle>(r)又会重新拷贝r到新的堆对象,所以返回的shared_ptr依然有效,自然能正常输出。

关于编译器优化的疑问

不存在“编译器优化导致变量未销毁”的情况——栈变量在作用域结束时一定会被销毁(其内存会被标记为可复用),但你的shared_ptr从始至终都没指向过栈变量,所以根本不存在悬空的场景。只有裸指针的情况才是真正的未定义行为,这类行为的表现完全不可预测,取决于编译器、运行环境等因素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:40:23