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

C++栈变量作用域疑问:栈销毁后为何仍能获取正确值?

解答:栈变量销毁后为何仍能输出正确值?

嘿,这个问题抓得很准,刚好能帮你理清栈、堆和static变量的核心区别,咱们一步步拆解你的代码:

首先看最关键的fun()函数:

static int* fun(){
    static int *ptr = new int(4);
    return ptr;
}

这里有两个核心要点:

  • ptr是static局部变量:它只会在第一次调用fun()时初始化一次,后续调用直接复用已有的指针值,不会重新执行new int(4)。
  • 指针ptr指向的是堆内存:用new分配的内存是在堆上的,堆内存不会随函数返回而被自动释放(除非你手动调用delete),生命周期从new执行开始,到delete执行结束。

接下来看tun()函数的核心操作:

int f = 111;
*(fun()) = f;

你说的没错,f确实是栈变量,tun()返回时栈帧会被销毁,f的内存空间会被标记为可复用,但这里的操作不是返回f的地址,而是把f的值(111)拷贝到了fun()返回的指针指向的堆内存里。相当于:

  1. 调用fun()拿到堆内存的指针(初始指向值为4的int)
  2. 把栈变量f的111赋值给这个堆上的int,此时堆里的int值更新为111
  3. 之后f虽然被销毁,但它的值已经被存在堆内存中,和栈空间没有关系了

最后梳理整个调用流程:

  • main() → sun() → tun()
  • tun()里先创建栈变量f=111,然后通过*(fun())=f把111写入堆内存
  • tun()再调用fun(),返回那个指向堆内存的指针(此时堆里的值是111)
  • 指针一路返回到main(),解引用后输出的是堆内存里的111,自然是正确的

误区澄清:如果tun()返回的是&f(栈变量的地址),那才会出现未定义行为(访问已销毁的栈内存),但你的代码里完全没有这么做——你操作的是堆内存,栈变量只是临时把值传递过去而已。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:17:50