Reputation: 3
Below is my code and the output for the same
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);
}
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
I was expecting the memory address to be the same when printed from the main() function as well as the move_function(). Could someone help me understand why they're different?
Upvotes: 0
Views: 94
Reputation: 22591
Moving a variable does exactly what it says: it moves it to a different location, so it has a different address.
That said, the actual content of the string is not moved, because for a String
type, only the stack part is moved. That is 24 bytes (on a 64 bit system):
If you move the string, those 24 bytes get moved. The content of the string, however, stays where it is:
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
Upvotes: 2
Reputation: 532
Moves are essentially a bit for bit copy (memcpy) under the hood, the only difference being that compiler also tracks ownership of the resource being moved, and doesn't allow access through the old owner after the move. So answering the question, move semantics just copies bits from source (old owner) to destination (new owner), thus changing the memory address.
Also in some cases, as far as I know, compiler might optimize away memcpy altogether, reusing the old address, but that is totally different topic.
Upvotes: 1