C++ / a working model

117 / 163   ·   C11   ·   8 min

The Abstraction: Address Spaces

Keep this sentence

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
  1. Almost No Memory Illusion on Early Machines
  2. Multiprogramming and Time-Sharing Force Concurrent Residence
  3. A Process’s Private View: Code, Heap and Stack
  4. The Core Task and Goals of Memory Virtualization
  5. Example
  6. Exercise

Official chapter PDF

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 && ./example

Expected 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.

Back to the catalog