To get the memory address of the pointer variable itself, you'd take the address of the pointer. In Rust, you can do this by taking a reference to the pointer variable and then converting it to a pointer:
fn main() { let x = 42; let ptr: *const i32 = &x as *const i32; // Get the address of the ptr variable itself let ptr_to_ptr: *const *const i32 = &ptr as *const *const i32; println!("Value of x: {}", x); println!("Address of x (value of ptr): {:p}", ptr); println!("Address of ptr variable itself: {:p}", ptr_to_ptr); unsafe { println!("Dereferencing ptr: {}", *ptr); // Gets 42 println!("Dereferencing ptr_to_ptr: {:p}", *ptr_to_ptr); // Gets the address of x } }
This creates a pointer to a pointer (double indirection). The type *const *const i32 means "a raw pointer to a raw pointer to an i32".
In memory, this looks like:
x(i32): Contains the value 42ptr(*const i32): Contains the address ofxptr_to_ptr(*const *const i32): Contains the address ofptr
This pattern of multiple levels of indirection is commonly used in low-level code, especially when implementing complex data structures or when interfacing with C APIs that use pointers to pointers.