I have a simple example where the behaviour of Rust does not match my mental image, so I am wondering what am I missing:
fn make_local_int_ptr() -> *const i32 {
let a = 3;
&a
}
fn main() {
let my_ptr = make_local_int_ptr();
println!("{}", unsafe { *my_ptr } );
}
Result:
3
This is not what I would expect. Using the notation given in The Stack and the Heap, I would expect the stack frame to look like this:
Address | Name | Value
-----------------------
0 | a | 3
inside make_local_int_ptr()
, but after this line,
let my_ptr = make_local_int_ptr();
Since a
goes out of scope, I would expect the stack to get cleared, but it apparently does not.
Furthermore, if I define another variable between creating my_ptr
and printing the dereferenced value of it:
fn main() {
let my_ptr = make_local_int_ptr();
let b = 6;
println!("{}", b); // We have to use b otherwise Rust
// compiler ignores it (I think)
println!("{}", unsafe { *my_ptr } );
}
My output is:
6
0
Which again is not what I expected, I was thinking:
Address | Name | Value
-----------------------
0 | b | 6
In which case my output would be:
6
6
or even (in C++ and Go I was getting this result):
Address | Name | Value
-----------------------
1 | b | 6
0 | a | 3
In which case my output would be:
6
3
Why am I getting the output that I am getting? Why is returning a pointer to a local variable even allowed? The variable goes out of scope, and the value where the pointer is pointing to becomes unpredictable.