117 / 163 · C11 · 8 min
The Abstraction: Address Spaces
This chapter shows how an operating system abstracts physical RAM into a private address space per process so that many programs can reside in memory at once, run safely, and still appear to own a large contiguous region starting at address zero.
In this lesson
Almost No Memory Illusion on Early Machines
The first computers handed physical memory to programs exactly as it was. The operating system occupied the lowest addresses and a single job used everything above it. Programmers worked with the raw layout; only one program executed at a time and isolation was essentially absent.
Multiprogramming and Time-Sharing Force Concurrent Residence
Machines were extremely expensive, so several jobs were kept ready at once. The operating system switched away from a process that waited for I/O, raising CPU utilization. Time-sharing later demanded interactive response; swapping an entire memory image to disk was far too slow, therefore several processes had to occupy physical RAM simultaneously and protection became urgent.
A Process’s Private View: Code, Heap and Stack
An address space is the entire memory a process believes it owns. Immutable instructions sit at the low end, the heap grows toward higher addresses for dynamic allocation, and the stack grows toward lower addresses from the top for locals and return addresses. Placing the two growable regions at opposite ends postpones collision. The true physical locations are chosen by the operating system and remain invisible to the process.
The Core Task and Goals of Memory Virtualization
The operating system must create the illusion that every process owns a huge private region starting at address zero, even though all processes share one physical memory and must not interfere. Hardware translation plus OS mapping tables accomplish this. The design goals are complete transparency to the program, fast translation, and strict isolation.
Pitfalls
- Believing virtual addresses are the same as physical addresses
- Placing heap and stack at the same end of the address space so they collide immediately
Run an example
Minimum C11 · complete program · Download .c
#include <stdio.h>
int main(void) {
puts("Address space simulation (virtual view):");
puts("0x0000: program code (text)");
puts("0x1000: heap start (grows up)");
puts("0xF000: stack start (grows down)");
puts("The OS maps these virtual addresses to physical RAM.");
return 0;
}
Compile locally
gcc -std=c11 -Wall -Wextra -Wpedantic -Werror ostep-13-address-spaces.c -o example && ./exampleExpected result
Address space simulation (virtual view):
0x0000: program code (text)
0x1000: heap start (grows up)
0xF000: stack start (grows down)
The OS maps these virtual addresses to physical RAM.
CHECK YOUR UNDERSTANDING
Close the answer. Explain it.
Why does a typical address space put the heap and stack at opposite ends rather than on the same side?
Show a reference answer
They can then grow toward each other independently and meet only when the process has truly exhausted nearly all of its space, maximizing usable dynamic memory.
Check the sources
Drafts and official chapters change. The version mark is only the example’s minimum.