为何被移动到函数的变量内存地址与原地址不同?
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
相关产品推荐
相关产品推荐

