A virtual address is a location a program can use to access data. It is not necessarily a location in physical RAM: the CPU translates it before the access. The operating system supplies the information used for that translation. section 6.4.3
Try printing the addresses of values you know exist instead of reading every address in a range. A byte-by-byte scan can reach an address the process is not allowed to access, causing the operating system to stop it. Printed addresses can look far apart even when the program uses little memory; values tend to cluster in pockets. section 6.4.2
Listing 6.14 Printing the address of variables within a program
static GLOBAL: i32 = 1000; #1
fn noop() -> *const i32 {
let noop_local = 12345; #2
&noop_local as *const i32 #3
}
fn main() {
let local_str = "a"; #4
let local_int = 123; #4
let boxed_str = Box::new('b'); #4
let boxed_int = Box::new(789); #4
let fn_int = noop(); #4
println!("GLOBAL: {:p}", &GLOBAL as *const i32);
println!("local_str: {:p}", local_str as *const str);
println!("local_int: {:p}", &local_int as *const i32);
println!("boxed_int: {:p}", Box::into_raw(boxed_int));
println!("boxed_str: {:p}", Box::into_raw(boxed_str));
println!("fn_int: {:p}", fn_int);}
This Rust program prints addresses for a global, local values, and boxed values. Compare the printed addresses; do not treat the pointer returned by `noop` as safe to dereference. section 6.4.2
GLOBAL: 0x7ff6d6ec9310 local_str: 0x7ff6d6ec9314 local_int: 0x23d492f91c boxed_int: 0x18361b78320 boxed_str: 0x18361b78070 fn_int: 0x23d492f8ec
One run’s output shows widely separated address clusters. Another run may print different addresses. section 6.4.2
The CPU’s memory management unit performs the translation using mapping information maintained by the operating system. Addresses are grouped into pages, typically 4 KB, rather than mapped separately for every variable. A cache called the translation lookaside buffer (TLB) keeps recent translations so repeated accesses need not take the slowest path. The exact arrangement varies by environment; some constrained systems use real addressing instead. section 6.4.3
