The behaviour of that program is undefined, which can be seen by running it under Miri, which is a Rust interpreter that can sometimes detect Undefined Behavior. (you can do this in the playground by clicking "Tools" (top right) -> "Miri"):
error: Undefined Behavior: pointer to alloc1039 was dereferenced after this allocation got freed
--> src/main.rs:9:25
|
9 | assert_eq!(unsafe { *dptr }, 1.0);
| ^^^^^ pointer to alloc1039 was dereferenced after this allocation got freed
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
What's happening here is a use-after-free: the Ok(v) => &v[0],
line moves data from v
(and thus res
), causing it to be freed. Later, data used for other variable overwrote the existing data (because using a pointer after the memory it points to is freed is Undefined Behaviour).
If you had tried to read the data out of the res
the normal way without unsafe
, you would have got a compile-time error for this very issue:
error[E0382]: use of partially moved value: `res`
--> src/main.rs:9:10
|
6 | Ok(v) => &v[0],
| - value partially moved here
...
9 | dbg!(res.unwrap()[0]);
| ^^^ value used here after partial move
|
= note: partial move occurs because value has type `Vec<f64>`, which does not implement the `Copy` trait
help: borrow this field in the pattern to avoid moving `res.0`
|
6 | Ok(ref v) => &v[0],
| +++
(playground)