A segment is a block within virtual memory. Dividing virtual memory into segments helps limit the space needed to translate virtual addresses into physical addresses. The CPU and operating system use these boundaries to reject unauthorized memory access, producing a segmentation fault. section 6.4.1 section 6.4.2
Scanning a process's memory
An unsafe Rust program can cast integers to pointers and scan memory byte by byte, but reading addresses that the process is not entitled to access causes a segmentation fault. Printing addresses of globals, locals, boxed values, and function-related values instead reveals how data is distributed across virtual addresses. 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);}
Inspect a Rust program that prints addresses for global, local, boxed, and function-related values, making virtual-address placement concrete. section 6.4.2

