CS210 · Block 5 · Lesson 38

Memory Layout Deep Dive

Text · Data · BSS · Heap · Stack · Virtual memory
At a glance: This is the synthesis lesson. Everything you have built this semester lives somewhere in memory, and today you learn the map: the five segments of a running C program, what lands in each one, and why. There is no new syntax to memorize. Instead you connect things you already know (globals, locals, the call stack, the heap) into one picture. The memory-map walkthrough in Section 5 lets you place objects segment by segment, and the capstone lab exercises all five at once.
Contents
  1. Lesson Objectives
  2. Assigned Readings
  3. Pre-Class Work
  4. Lesson Materials and Overview
  5. In-Class Work
  6. After Class
1. Lesson Objectives

By the end of this lesson, cadets will be able to:

  1. Identify the standard memory segments of a running C program: text, data, BSS, heap, and stack. (Outcome 2)
  2. Predict which segment a given program element occupies, including globals, statics, locals, string literals, and dynamically allocated data. (Outcome 2)
  3. Explain at a high level how virtual memory gives each process its own private address space on top of shared physical memory. (Outcome 2)
2. Assigned Readings

Complete before class. The instructor notes and diagram below are the primary reading; the optional source goes deeper.

Source Sections Why
Instructor notes (Section 4 below, with diagram) All The five segments and what lands in each. This is the required reading.
Beej-C Pointers and Manual Memory Allocation (review) Optional refresher on the heap and pointers from earlier blocks.
3. Pre-Class Work
Do this first
Plan on about 20 minutes. This is a conceptual lesson, so the reading is short. Come to class ready to predict where things live, then prove it in the walkthrough.

Pre-Class Checklist

1
Read the instructor notes and study the diagram in Section 4
Learn the five segments and what lives in each. You should be able to name them top to bottom and give one example of something that lives in each before you walk in.
2
Refresh two earlier ideas
This lesson ties together the call stack (the recursion lesson) and the heap (dynamic memory with malloc and free). If either feels rusty, skim your notes from those lessons before class.
3
Skim the In-Class section below
You will see an interactive memory-map walkthrough. No need to use it yet; just know it is there and what it looks like.
4. Lesson Materials and Overview

You have spent the semester declaring variables, calling functions, and allocating memory with malloc. Each of those things ends up in a specific region of memory, and the region is not arbitrary. Today you learn the map of a running C program and the two questions that decide where anything lives.

Jump to
Slides The Map The Five Segments Two Questions Virtual Memory DFCS Standard

Slides

The Lesson 38 deck walks the memory map from top to bottom, places examples in each segment, and closes by looking ahead to your team presentations. The slides are the spine of the in-class lecture; the memory-map walkthrough is where you practice placing things yourself.

Open Lesson 38 slides → replace href with your SharePoint link

The map of a running program

When your program runs, the operating system gives it an address space: a range of memory addresses laid out from high to low. That space is divided into regions, each with its own job and its own rules. High addresses sit at the top; the lowest addresses at the bottom. This is the single picture to carry out of this lesson.

A C Process in Memory One running program's virtual address space, high addresses at top High addresses 0x0 (low) Stack Function parameters, local variables, return addresses. One frame per active call. Reclaimed automatically when a function returns. grows down unused virtual address space the stack and the heap grow toward each other here Heap Memory you request at run time with malloc / calloc / realloc. You decide its lifetime. You must free it. grows up BSS (uninitialized data) Globals and statics with no initializer. Zeroed at startup; costs no space in the executable file. Data (initialized data) Globals and statics that have a starting value. Lives for the entire run of the program. Text (code) The machine code of your functions. String literals and const data sit in a read-only region alongside it. Read-only: writing here crashes the program. Where things land int x; inside a function → Stack malloc(n) → Heap static int n; → BSS int g = 5; at file scope → Data "hello" and your code → Text CS210 / Lesson 38 / Memory Layout Deep Dive

The five segments of a C process, with the stack and heap growing toward each other through the unused middle.

The five segments

Read the map from the bottom up, because that is roughly the order in which things are decided, from fixed-at-compile-time to decided-at-run-time.

Segment What lives here Lifetime
Text Your compiled code, plus string literals and other read-only constants. Whole run. Read-only; writing here crashes.
Data Globals and statics that have an initial value. Whole run.
BSS Globals and statics with no initializer. Zeroed at startup. Whole run. Costs no bytes in the executable file.
Heap Memory you request at run time with malloc, calloc, realloc. From your malloc until your free. Your responsibility.
Stack Function parameters, local variables, and return addresses. One frame per active call. Reclaimed automatically when the function returns.

The pointer trap. A line like animal_t *p = malloc(sizeof(animal_t)); creates two objects in two different segments. The pointer variable p lives on the stack; the block it points to lives on the heap. When the function returns, the stack reclaims p automatically, but the heap block stays allocated until you free it. Forgetting that is exactly the leak that valgrind reports.

Two questions decide everything

You do not need to memorize a table of cases. For any variable, two questions place it:

  1. What is its scope and lifetime? A plain local inside a function goes on the stack. Anything at file scope, or marked static, lives for the whole run and goes in data or BSS. Anything from malloc goes on the heap.
  2. Does it have an initializer? For whole-run variables, an initial value puts it in data; no initializer puts it in BSS.

Notice that scope, not syntax, decides the home. The exact same line int n = 5; goes on the stack inside a function and into the data segment at file scope. That is the single most useful idea in this lesson, and the walkthrough drills it directly.

Virtual memory, briefly

The address space in the diagram is virtual. Every running program sees the same clean layout starting from low addresses, as if it owned the whole machine. It does not. The operating system maps each program's virtual addresses onto whatever physical memory is actually free, and keeps each program's space private from the others.

Two practical consequences follow. First, the addresses you print are virtual, so the same program run twice can report different numbers (modern systems also randomize the layout on purpose for security). Second, one program cannot read or corrupt another's memory by accident, because they do not share an address space. You do not need the page-table details for this course. You need the mental model: each process gets its own private map, and the diagram is that map.

DFCS C Programming Standard

This lesson does not introduce a new style rule; it reinforces one you already follow. The heap discipline in §8.5 (every allocation has a matching free; no leaks) is exactly what the memory map makes concrete. The stack reclaims its frames for you, but the heap is yours to manage. The capstone lab is graded in part on a clean valgrind run, which is the standard's no-leak rule made measurable. The full standard lives in the course Resources section.

5. In-Class Work

Two things to do in class. Use the checklist to track your progress.

  • Work through the memory-map walkthrough below. Twelve guided tasks across four sections. Declare or allocate what each task asks for, predict the segment, then watch the map fill in. About 20 minutes.
  • Start the capstone lab: Aspen Humane Society Roster. Your synthesis lab. Auto-graded through GitHub Classroom and Gradescope.
    This lab is due at Lesson 40, not next lesson. The extra time is on purpose: treat it as a real warmup for the final.

Memory-Map Walkthrough

Twelve tasks across four sections. Each task names a scope (file scope, or inside main). Decide which segment the object lands in before you press Enter, then type the declaration and watch the right pane.

Memory Map: where does each thing live?

Declare or allocate what each task asks for. Before you press enter, decide which segment it lands in — then watch the map.

Task 1 of 12
Section 1: Globals split in two
scope
Task 1 of 12
Loading…
file>

Before you start

Enter your name. It will appear on the completion screen so you can include it in your screenshot for the Lesson 38 reflection.

6. After Class
  • Keep working the capstone lab. It is due at Lesson 40; get to a clean valgrind run before you submit.
  • Complete the Lesson 38 reflection in Blackboard. Use your completion code from the walkthrough and attach your screenshot.
  • Replay the walkthrough in free mode. Try your own declarations and allocations and predict the segment before you press Enter.
  • Heads up: team PEX presentations are at Lesson 39, then review at Lesson 40 and the final at Lesson 41. The memory map is fair game on the final.
Need help? Schedule EI with your instructor. For the capstone, bring your shelter.c, the exact compiler or valgrind message you do not understand, and the line it points at. Specific questions get unstuck quickly.