Search code examples
pointersmemory-managementrustunsafe-pointers

Dereferencing raw pointer with explicit annotation in Rust


I was writing unsafe snippet of code to emulate how C would have allocated a memory for an int. The code allocates memory for an isize type, assign 0 to the pointer variable, then infinitely increment the value at the address every second

use std::process;
use std::{thread, time};
use std::alloc::{alloc, Layout};

fn main() {
    unsafe {
        let layout = Layout::new::<isize>();
        let p = alloc(layout);
        println!("({}) address pointed to by p: {:p}", process::id(), p);
        *(p as *mut isize) = 0;
        loop {
            thread::sleep(time::Duration::from_millis(1000));
            *(p as *mut isize) += 1;
            println!("({}) p: {}", process::id(), *(p as *mut isize));
        }
    }
}

However, for each *(p as *mut size) I could have replaced with just *p without the compiler complaining (i.e. *p = 0;), thus I assumed it was correctly inferred. I need help explaining the difference and in which case the explicit type annotation may be required.


Solution

  • It's not correctly inferred. alloc returns a pointer to u8, which can be set to 0 or incremented, so the compiler doesn't complain. However it will wrap at 255 instead of wrapping at 4G (or whatever if you're on a 64-bit system).