As I was trying to work through an example sharing a read-only string among threads.
While it seems the "right" way would be to wrap the string in an Arc::new
i was confused by the result of the following code.
I thought this would create 3 copies of the original string for the 3 threads. However if I understand the output correctly I get one copy only.
If I understand correctly using :p
we get the address of the variable on the stack and the as_ptr
call returns the location of the content of the string in the heap.
So why are the 3 printed from the threads showing the same values?
fn main() {
let answer = String::from("Hello World!");
println!("Before: {answer} {:p} {:?}", &answer, answer.as_ptr());
for _ in 1..=3 {
let answer = answer.clone();
let handle = std::thread::spawn(move || {
println!(
"{:?} {} {:p} {:?}",
std::thread::current().id(),
answer,
&answer,
answer.as_ptr()
);
});
handle.join().unwrap();
}
println!("After: {answer} {:p} {:?}", &answer, answer.as_ptr());
}
Before: Hello World! 0x7ffec81bf918 0x5c8c20f18b80
ThreadId(2) Hello World! 0x7b2f151ffb70 0x5c8c20f18ba0
ThreadId(3) Hello World! 0x7b2f151ffb70 0x5c8c20f18ba0
ThreadId(4) Hello World! 0x7b2f151ffb70 0x5c8c20f18ba0
After: Hello World! 0x7ffec81bf918 0x5c8c20f18b80