I want to convert *mut
pointer to &mut
reference.
// Both setting a value to ptr and getting a value from ptr succeeds.
let ptr: &mut usize = unsafe { &mut *(VIRTUAL_ADDRESS_TO_ACCESS_FREE_PAGE as *mut usize) };
This works. However, if &mut
is outside of unsafe
block, the code will not work partially. *ptr = foo
will not store foo
to the memory ptr
points, but let foo = *ptr
will assign the value of *ptr
to foo
.
// Setting a value to ptr fails, but getting a value from ptr succeeds.
let ptr: &mut usize = &mut unsafe { *(VIRTUAL_ADDRESS_TO_ACCESS_FREE_PAGE as *mut usize) };
What's the difference between unsafe { &mut }
and &mut unsafe{ }
?
It doesn't have anything to do with unsafe
per-se, rather with block boundaries.
&*ptr
is a "reborrow", it's just going to reinterpret the pointer to a new form. So you get different types of pointers (one raw and one reference) to the same object.
&{*ptr}
is completely different, because {*ptr}
will force a copy[0] (thanks @harmic for the sourcing):
Blocks are always value expressions and evaluate the last expression in value expression context. This can be used to force moving a value if really needed.
Then it will borrow that copy. This means you get two pointers to completely different objects.
The objects have the same value since one's pointee is a copy of the other's, and thus reading seems to work, but writing doesn't because... you're not writing where you think you are.
See this demonstration (not using mut pointers because there's no need to to demonstrate the issue)
[0] more generally a move but here you're pointing to a usize
which is Copy
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With