Process Memory Layout
A running C program’s virtual address space has five regions:
| Region | Contents | Typical address (x86-64 Linux) |
|---|---|---|
| Stack | Local variables, function args, return addresses | Near 0x7fff... (high) |
| Heap | malloc/free allocations | Mid-range (0x5... – 0x7f...) |
| BSS | Zero-initialized globals (int x;) | Low (0x40... – 0x60...) |
| Data | Initialized globals (int x = 5;) | Adjacent to BSS |
| Text | Machine code + string literals (read-only) | Lowest |
Key Rules
- Stack grows downward (toward lower addresses on x86). Outer frames have higher addresses than inner frames.
- Heap grows upward (toward higher addresses). Each
mallocmay callbrk/mmapif the allocator has no free block. - String literals (
"hello") live in the text/rodata segment — read-only. Writing to them is undefined behaviour and typically causesSIGSEGV. - BSS variables are zero-initialized before
mainruns. Data variables are initialized to their specified value. Both persist for the full lifetime of the process.
Diagnostic: identifying a pointer’s region
From the address alone you can identify which region a pointer belongs to:
printf("stack: %p\n", (void*)&local); /* 0x7fff... */
printf("heap: %p\n", (void*)malloc(1)); /* 0x55... */
printf("text: %p\n", (void*)main); /* 0x40... */
printf("lit: %p\n", (void*)"hello"); /* 0x40... same range as text */This pattern is consistent across Linux processes and is a practical first step when debugging an unexpected crash — the address tells you which allocator or scope owns the memory.
Stack Overflow
The stack has a fixed limit (~8 MB on Linux, set by ulimit -s). Infinite
recursion or very large stack allocations exhaust it. The OS signals SIGSEGV
when the stack pointer crosses into an unmapped guard page.
Relationship to Debugging Tools
- Valgrind and ASan track heap allocations and flag out-of-bounds accesses and use-after-free — they only monitor heap memory.
- GDB can inspect variables in any region via
printandx/Nxb addr. - The
/proc/<pid>/mapsfile shows the exact layout of a running process including library segments and anonymous mmap regions.
Appears In
m01-c-is-not-java, m02-pointers-memory-model, m03-dynamic-memory