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()返回的指针指向的堆内存里。相当于:
- 调用
fun()拿到堆内存的指针(初始指向值为4的int) - 把栈变量
f的111赋值给这个堆上的int,此时堆里的int值更新为111 - 之后
f虽然被销毁,但它的值已经被存在堆内存中,和栈空间没有关系了
最后梳理整个调用流程:
main()→sun()→tun()tun()里先创建栈变量f=111,然后通过*(fun())=f把111写入堆内存tun()再调用fun(),返回那个指向堆内存的指针(此时堆里的值是111)- 指针一路返回到
main(),解引用后输出的是堆内存里的111,自然是正确的
误区澄清:如果tun()返回的是&f(栈变量的地址),那才会出现未定义行为(访问已销毁的栈内存),但你的代码里完全没有这么做——你操作的是堆内存,栈变量只是临时把值传递过去而已。
内容的提问来源于stack exchange,提问作者Umar Farooq
相关产品推荐
相关产品推荐

