C++右值引用绑定临时对象返回的内部引用为何未触发段错误
问题解答
你的理解没有偏差,这段代码确实存在悬空引用,属于C++标准规定的未定义行为,未触发段错误只是未定义行为的常见表现,不代表代码逻辑合法。
具体原因拆解:
- 临时对象
S()的生命周期仅维持到auto &&x = S().func();这一完整表达式执行结束。该行执行完成后,S实例及其内部的std::map成员都会被析构,func()返回的引用指向的内存已经被释放,x确实是悬空引用。 - 未触发段错误的核心逻辑是:内存释放只是标记该块内存可被重新分配,不会立刻清除内存内容、也不会立刻触发操作系统回收内存页。只要这块内存还没有被新的分配操作覆盖、也没有被系统回收,读取操作就会读到旧的残留值,不会触发访问非法内存的段错误。
- 你可以通过修改代码复现异常:在引用定义和打印操作之间插入大量内存分配逻辑(比如创建多个大对象、向容器中插入大量元素),大概率会读取到异常值,甚至直接触发段错误。
补充说明:只有直接将临时对象绑定到引用时,才会触发C++的临时对象生命周期延长规则。你这里绑定的是临时对象内部成员的引用,不属于该规则的覆盖范围,因此原临时对象不会因为成员引用被绑定而延长生命周期,和你查阅的范围for循环的悬空引用场景规则完全一致。
你提供的测试代码:
#include <iostream> #include <string> #include <map> using namespace std; struct S { map<int, int> m; S() { m[24] = 5; } const int &func() const { return m.find(24)->second; } }; int main() { auto &&x = S().func(); std::cout<<"\n value is "<<x; return 0; }
内容的提问来源于stack exchange,提问作者user3219492
相关产品推荐
相关产品推荐

