Rust中引用关联的临时变量为何未在作用域结束后销毁?
Rust中局部变量与常量字面量的内存行为差异解释
一、scope_1 和 scope_2 的行为分析
在scope_1和scope_2中,代码是在栈上创建局部变量:
let ui: u8 = 1; // 栈上分配局部变量
函数执行结束时,对应的栈帧会被销毁,局部变量占用的内存会被释放,此时返回的指针指向的是已失效的栈内存。后续通过这个指针读取值属于未定义行为,打印出的0只是内存被覆盖后的随机结果。
至于两个函数返回的指针地址相同,是因为函数调用的栈帧结构一致,栈空间被重复利用导致的,这是栈内存的正常特性。
二、scope_3、scope_4 和 scope_5 的行为分析
这三个函数里的代码是取常量字面量的引用:
let uip: &u8 = &3; // 取常量字面量3的引用
Rust编译器会将这类编译期已知的常量字面量存储在程序的静态内存区域(而非栈上),静态内存的生命周期和程序完全一致,不会随函数返回而销毁,所以返回的指针始终有效,读取到的值也符合预期。
- scope_3和scope_4地址相邻:因为
3和4是不同的常量字面量,编译器会为它们分别分配独立的静态内存空间,而u8类型占1字节,所以两个地址恰好相邻。 - scope_5复用scope_3的地址:编译器会执行常量合并优化——相同的常量字面量只会在静态内存中存储一份。所以当
scope_5再次引用&3时,直接复用了之前scope_3中3的内存地址,不需要重新分配空间。
总结
两种场景的核心差异在于:
- 栈上的局部变量会随函数栈帧销毁而失效;
- 编译期常量字面量会被放入静态内存,且相同常量会被合并复用,生命周期贯穿整个程序运行过程。
内容的提问来源于stack exchange,提问作者Tr3nchHvlk
相关产品推荐
相关产品推荐

