Happens when a program tries to access memory outside of its memory segmentation.
Common causes include:
-
Stack overflow: Size of stack exceeds its allocated maximum
- Infinite recursion/deep nested calls
- Large variables (usually tuples/array)
- VLAs in unsafe code (variable-length arrays via FFI)
- Compiler bug (very rare)
-
Null pointer dereference - OS marks null pointer or
0x0as inaccessible/protectedunsafe { let ptr: *const i32 = std::ptr::null(); let _ = *ptr; // SIGSEGV } -
Use-after-free: Trying to access a pointer after it has been freed (dangling pointer)
- Heap (majority)
unsafe { let ptr = Box::into_raw(Box::new(42)); drop(Box::from_raw(ptr)); let _ = *ptr; // Use-after-free } - Stack
fn dangling() -> &'static i32 { let x = 42; unsafe { &*(&x as *const i32) } // Returns pointer to stack memory } // x deallocated when function returns // Using the returned reference = use-after-free - Static
unsafe { static mut PTR: *mut i32 = std::ptr::null_mut(); PTR = Box::into_raw(Box::new(42)); drop(Box::from_raw(PTR)); let _ = *PTR; // Use-after-free }
- Heap (majority)
-
Writing to read-only memory (.rodata: string literals, static immutable data)
-
Out-of-bounds: Reading beyond allocated memory
let arr = [1, 2, 3]; let val = arr[1000]; // Read past bounds -
Buffer overflow: Writing beyond allocated memory
let mut arr = [1, 2, 3]; arr[1000] = 42; // Write past bounds -
Accessing unmapped memory: Accessing memory not allocated to process
unsafe { let ptr = 0xDEADBEEF as *const i32; let _ = *ptr; // SIGSEGV - address not mapped }