You have a number of issues here, none of which relate to copying a pointer.
I see what you're trying to do, but you're seeing 'undefined behavior' in action, not a failure to copy the pointer value.
First of all, this:
temp_b.next.unwrap()
Unwrap does not leave the object behind; it consumes it. Every iteration through, you will be setting the value of next to nothing as you call unwrap.
Secondly, on the first iteration through your loop, you convert the original pointer into a box:
let mut p: *mut ListNode = self as *mut ListNode;
// ... p is not reassigned before calling the next statement
Box::from_raw(p);
As a result, you're dropping (free'ing) the root object a when you consume temp_b.
This won't immediately trigger a crash, but it means you've now effectively corrupted the stack. Everything past this point is undefined behavior.
Look at the output when you trace your actual pointer values:
#[derive(Debug)]
struct ListNode {
val: String,
next: Option<Box<ListNode>>,
}
impl ListNode {
fn new(i: &str) -> Self {
ListNode { val: format!("{:?}", i), next: None }
}
fn add_l(&mut self, l: &Vec<&str>) {
let mut p: *mut ListNode = self as *mut ListNode;
println!("self -> {:?}", self as *mut ListNode);
for i in l {
unsafe {
(*p).next = Some(Box::new(ListNode::new(*i)));
let temp_b = Box::from_raw(p);
println!("{:?} -> {:?}", p, temp_b);
p = Box::into_raw(temp_b.next.unwrap());
println!("next p -> {:?}", p);
};
}
println!("self -> {:?}", self as *mut ListNode);
}
}
fn main() {
let mut a = ListNode::new("1");
a.add_l(&vec!["2", "3", "4", "5"]);
println!("self -> {:?}", &mut a as *mut ListNode);
println!("{:?}", a);
}
...
self -> 0x7ffdc10a90f0
0x7ffdc10a90f0 -> ListNode { val: "\"1\"", next: Some(ListNode { val: "\"2\"", next: None }) }
next p -> 0x7fdde801f060
0x7fdde801f060 -> ListNode { val: "\"2\"", next: Some(ListNode { val: "\"3\"", next: None }) }
next p -> 0x7ffdc10a90f0
0x7ffdc10a90f0 -> ListNode { val: "\"3\"", next: Some(ListNode { val: "\"4\"", next: None }) }
next p -> 0x7fdde801f060
0x7fdde801f060 -> ListNode { val: "\"4\"", next: Some(ListNode { val: "\"5\"", next: None }) }
next p -> 0x7ffdc10a90f0 <---- Whhhaaaat! You've been reallocated!
self -> 0x7ffdc10a90f0
self -> 0x7ffdc10a90f0
ListNode { val: "\"5\"", next: None }
So... this is why using unsafe is unsafe.
You can't do what you want to do without using raw pointers all the way; I recommend you look at Rc for what you're trying to do.