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

为何访问已超出作用域的对象仍能得到「正确」输出?

问题说明

以下代码可能会打印10,但assign函数中创建的Test1对象t1在执行打印操作时已经被销毁,那么Test2对象t2的ptr指针是否指向仍保留值10的未分配内存空间?

#include <iostream>

class Test1 {
public:
     int a;
};

class Test2 {
public:
     Test1* ptr;
};

void assign(Test2& t2) {
     Test1 t1{10};
     t2.ptr = &t1;
}

int main() {
     Test2 t2;
     assign(t2);
     std::cout << t2.ptr->a << std::endl;
     return 0;
}
解答

这属于C++中的未定义行为,没有任何规则能保证你读到的一定是10,也不能认为这块内存还保留着原来的值:

  • t1是assign函数的局部变量,存储在栈内存中。当函数执行完毕返回时,对应的栈帧会被销毁,t1占用的内存空间会被标记为可被后续代码复用,但不会立刻被清空。
  • 你偶尔能读到10,只是因为这块内存还没被其他操作覆盖,这是完全随机的巧合。如果在assign返回后、打印前插入其他函数调用或者变量操作,这块内存很可能被新数据覆盖,此时再访问ptr就会得到错误的值,甚至直接导致程序崩溃。
  • 此时t2.ptr是悬垂指针,指向已经失效的内存区域。C++标准明确规定,通过悬垂指针访问数据的行为是未定义的,程序的任何表现都是合法的,不能依赖这种偶然的“正常输出”。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:19:56