rust 为什么传递给函数(移动)的变量的内存位置与原始内存地址不同?

dgenwo3n  于 2023-02-08  发布在  其他
关注(0)|答案(2)|浏览(178)

下面是我的代码和相同的输出

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);
}

Output

The output for the above code is 
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()函数输出的内存地址是一样的,有人能帮我理解为什么它们不同吗?

u3r8eeie

u3r8eeie1#

移动变量的作用与它所表示的完全相同:它会将其移动到不同的位置,因此它具有不同的地址。
也就是说,字符串的实际content没有移动,因为对于String类型,只有栈部分被移动,也就是24字节(在64位系统上):

  • 8字节:指向堆上实际字符串内容的指针
  • 8字节:字符串的大小
  • 8字节:分配的内存大小。如果字符串超过这个值,就会发生重新分配。

如果移动字符串,这24个字节也会移动,但字符串的内容会保持不变:

fn main() {
    let a: String = String::from("variable a");
    println!("main: variable: {}", a);
    println!("main: variable mem location: {:p}", &a);
    println!("main: content mem location: {:p}", a.as_ptr());
    println!("main: size: {} bytes", std::mem::size_of_val(&a));
    move_function(a);
}

fn move_function(a: String) {
    println!("move_function: variable: {}", a);
    println!("move_function: variable mem location: {:p}", &a);
    println!("move_function: content mem location: {:p}", a.as_ptr());
    println!("move_function: size: {} bytes", std::mem::size_of_val(&a));
}
main: variable: variable a
main: variable mem location: 0x7ffc8e535ca8
main: content mem location: 0x55d52597dad0
main: size: 24 bytes
move_function: variable: variable a
move_function: variable mem location: 0x7ffc8e535de0
move_function: content mem location: 0x55d52597dad0
move_function: size: 24 bytes
jjhzyzn0

jjhzyzn02#

移动本质上是一种位对位的复制(memcpy),唯一的区别是编译器还跟踪被移动资源的所有权,并且在移动后不允许通过旧所有者访问。因此,回答这个问题,移动语义只是将位从源(旧所有者)复制到目标(新所有者),从而改变内存地址。
而且在某些情况下,据我所知,编译器可能会完全优化掉memcpy,重用旧地址,但那是完全不同的主题。

相关问题