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

为何被移动到函数的变量内存地址与原地址不同?

Rust移动语义下变量内存地址差异解析

代码示例

fn main() {
    let a : String = String::from("variable a");
    println!("variable from main fun : {}", a);
    println!("variable mem location {:p} ", &a);
    move_function(a);
}

fn move_function(a: String) {
    println!("variable from move_function fun : {}", a);
    println!("variable mem location from move_function {:p} ", &a);
}

运行输出

variable from main fun : variable a
variable mem location 0x7fff11676c70 
variable from move_function fun : variable a
variable mem location from move_function 0x7fff11676d10 

问题

我原本认为在main()函数和move_function()中打印的变量内存地址应该相同,想请教为何二者存在差异?

解答

核心原因是混淆了**String的栈存储结构和堆数据地址**:

  • Rust的String并非直接存储字符串内容,而是栈上的一个三元结构:指向堆内存的指针、字符串长度、容量。
  • 执行move_function(a)时发生所有权转移(Move语义):main栈帧中的a结构会被复制到move_function的参数栈帧中,但堆上的实际字符串数据不会被复制。
  • 你打印的&a是栈上这个三元结构的地址,main和move_function拥有各自独立的栈帧,所以两个a的栈地址自然不同。
  • 若要验证堆上数据未被复制,可以打印a.as_ptr(),该方法返回堆中字符串的起始地址,两次打印结果会完全一致。

验证代码

fn main() {
    let a : String = String::from("variable a");
    println!("variable from main fun : {}", a);
    println!("stack location of a: {:p}", &a);
    println!("heap location of string data: {:p}", a.as_ptr());
    move_function(a);
}

fn move_function(a: String) {
    println!("variable from move_function fun : {}", a);
    println!("stack location of a in move_function: {:p}", &a);
    println!("heap location of string data in move_function: {:p}", a.as_ptr());
}

运行该代码会看到:栈地址不同,但堆地址完全相同,印证了Move语义仅转移栈上的指针结构,而非复制堆数据。

内容的提问来源于stack exchange,提问作者Vishnu TP

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:37:12