C++局部变量引用存入全局容器后第二段代码为何未报错
问题本质:两份代码均属于未定义行为
你看到的第二份代码“正常运行”只是未定义行为的典型表现,不代表代码本身没有问题。
核心原因
- 两份代码都犯了同样的错误:将局部作用域内创建的对象的引用存入容器,对象离开作用域被销毁后,容器里存储的变成悬空引用,访问悬空引用的行为在C++标准中属于未定义行为,没有任何可预期的结果。
- 局部对象销毁时,操作系统/编译器只会标记该对象对应的栈内存为“可复用”,不会主动清空内存中存储的原始数据:
- 第一份代码里的局部
aa定义在foobar函数的栈帧中,函数返回后栈帧被回收,后续调用std::cout、getName等操作会直接复用这块栈内存,覆盖原来的aa对象数据,所以访问时直接出现错误。 - 第二份代码里的局部
aa定义在main函数的内层作用域中,离开作用域后对应的栈内存暂时没有被其他操作覆盖,存储的name字符串值还保留在原地,所以读取时看起来是“正常”的。这个结果完全是巧合,没有任何可靠性:换编译器版本、开启O2及以上优化、在内层作用域结束和cout之间加几行定义局部变量/调用其他函数的代码,都会直接触发乱码、崩溃等错误表现。
- 第一份代码里的局部
注意:永远不要依赖未定义行为的偶然表现判断代码正确性,只要存在悬空引用/指针,代码本身就是错误的。
内容的提问来源于stack exchange,提问作者null
相关产品推荐
相关产品推荐

