I came across this strange phenomenon while playing with unsafe Rust. I think this code should make a segmentation fault but it does not. Am I missing something? I tried to set a pointer to a variable with a shorter lifetime and then dereference it.
// function that sets a pointer to a variable with a shorter lifetime
unsafe fn what(p: &mut *const i32) {
    let a = 2;
    *p = &a;
    //let addr = *p;    // I will talk about this later
    println!("inside: {}", **p);
}
fn main() {
    let mut p: *const i32 = 0 as *const i32;
    unsafe {
        what(&mut p);
        // I thought this line would make a segfault because 'a' goes out of scope at the end of the function making the address invalid
        println!("segfault? {}", *p);
        // Even more unsettling: I can increment the address and still dereference it.
        p = ((p as usize) + 1) as *const i32;
        println!("I'm definitely missing something: {}", *p);
    }
}
This program outputs:
inside: 2
segfault? {random number around 20000. probably uninitialized memory but why?}
I'm definitely missing something: {uninitialized memory}
If I uncomment the line
let addr = *p;
the second row becomes
segfault? 2
Why is there no segfault? Can the compiler extend the lifetime of a or the address p points at for safety? Am I missing some basic information about pointers in Rust?
 
    