Chapter 22Advanced

C Program Memory Layout

See how C programs are organized in RAM! Learn about Stack, Heap, Data, BSS, and Text segments. Essential for understanding memory.

18 min readUpdated 2024-12-16
memory layoutstackheapdata segmentbsstext segmentRAM

What You Will Learn

  • Visualize the 5 memory segments
  • Know what goes in Stack vs Heap
  • Understand global vs local variable storage
  • Use size command to check segment sizes

01Introduction to Memory Layout

🧠 What is Memory Layout?

When you run a C program, the operating system loads it into RAM (Random Access Memory). The memory is organized into distinct segments, each with a specific purpose. Understanding this layout helps you write efficient code and debug memory issues.

📦 The 5 Memory Segments

Text

Code

Data

Initialized

BSS

Uninitialized

Heap

Dynamic

Stack

Local/Calls

02Memory Layout Diagram

Memory Layout (Low Address → High Address)

High Address (0xFFFF...)
Command-line Arguments

argc, argv, environment

STACK

Local variables, function calls

↓ Grows Down
↕ Free Space ↕
↑ Grows Up
HEAP

malloc(), calloc(), dynamic memory

BSS (Uninitialized Data)

Uninitialized global/static variables

DATA (Initialized)

Initialized global/static variables

TEXT (Code)

Compiled machine instructions

Low Address (0x0000...)

💡 Key Insight

Stack grows DOWN (toward lower addresses) while Heap grows UP (toward higher addresses). They grow toward each other from opposite ends!

03Text Segment (Code Segment)

📝 What is the Text Segment?

The Text Segment stores your compiled code — the machine instructions (binary) that the CPU executes.

PropertyValue
ContainsMachine code (compiled instructions)
PermissionRead-only (execute)
LocationLowest memory addresses
Why Read-only?Prevent accidental modification of code
text_segment.c
C
1#include <stdio.h>
2
3// All this code goes to TEXT segment
4int add(int a, int b) {
5 return a + b; // Instructions stored in TEXT
6}
7
8int main() {
9 int result = add(5, 3); // Call instruction in TEXT
10 printf("Sum: %d\n", result);
11 return 0;
12}

Remember: Your actual printf(), add(), and main()function instructions are stored here as binary code!

04Initialized Data Segment

📝 What is the Data Segment?

Stores global and static variables that are initialized with a value by the programmer.

Read-Write Section

Variables that CAN be changed

int score = 100;

static float rate = 0.05;

Read-Only Section

Constants (cannot be changed)

const int MAX = 100;

char *msg = "Hello";

data_segment.c
C
1#include <stdio.h>
2
3// Global initialized variables → DATA segment
4int playerScore = 500;
5char *gameName = "Space Invaders";
6const int MAX_LIVES = 3;
7
8int main() {
9 // Static initialized variable → DATA segment
10 static int level = 1;
11
12 printf("Game: %s\n", gameName);
13 printf("Score: %d, Level: %d\n", playerScore, level);
14 printf("Max Lives: %d\n", MAX_LIVES);
15
16 return 0;
17}
Output

Game: Space Invaders

Score: 500, Level: 1

Max Lives: 3

05BSS Segment (Uninitialized Data)

📝 What is BSS?

BSS (Block Started by Symbol) stores global and static variables that are NOT initialized (or initialized to 0). The kernel automatically sets them to 0 before execution.

💡 Automatic Initialization

Variables in BSS are automatically initialized to:
Numbers: 0
Pointers: NULL
Characters: '\0'

bss_segment.c
C
1#include <stdio.h>
2
3// Uninitialized global → BSS (auto-initialized to 0)
4int totalUsers;
5char username[50];
6float balance;
7
8int main() {
9 // Uninitialized static → BSS (auto-initialized to 0)
10 static int loginCount;
11
12 printf("Total Users: %d\n", totalUsers); // 0
13 printf("Login Count: %d\n", loginCount); // 0
14 printf("Balance: %.2f\n", balance); // 0.00
15
16 // Empty string (first char is '\0')
17 printf("Username: '%s'\n", username);
18
19 return 0;
20}
Output

Total Users: 0

Login Count: 0

Balance: 0.00

Username: ''

⚠️ BSS vs Data

int x; → BSS (uninitialized, auto = 0)
int x = 0; → DATA (explicitly initialized)
int x = 5; → DATA (explicitly initialized)

06Heap Segment (Dynamic Memory)

📝 What is the Heap?

The Heap is for dynamic memory allocation — memory you request at runtime using malloc(), calloc(), and realloc().

PropertyValue
GrowsUpward (toward higher addresses)
Managed ByProgrammer (malloc/free)
LifetimeUntil free() is called
SizeLimited by available RAM
heap_segment.c
C
1#include <stdio.h>
2#include <stdlib.h>
3
4int main() {
5 // Allocate array on HEAP
6 int *scores = (int *)malloc(3 * sizeof(int));
7
8 if (scores == NULL) {
9 printf("Memory allocation failed!\n");
10 return 1;
11 }
12
13 // Use heap memory
14 scores[0] = 85;
15 scores[1] = 92;
16 scores[2] = 78;
17
18 printf("Scores: %d, %d, %d\n", scores[0], scores[1], scores[2]);
19
20 // Free heap memory
21 free(scores);
22 scores = NULL;
23
24 return 0;
25}
Output

Scores: 85, 92, 78

07Stack Segment

📝 What is the Stack?

The Stack stores local variables, function parameters, and return addresses. It follows LIFO (Last In, First Out).

PropertyValue
GrowsDownward (toward lower addresses)
ContainsLocal variables, parameters, return address
Managed ByCompiler (automatic)
LifetimeUntil function returns
stack_segment.c
C
1#include <stdio.h>
2
3void greet(char *name, int age) {
4 // name and age are on STACK (parameters)
5 char message[50]; // Local array on STACK
6
7 printf("Hello %s, you are %d years old!\n", name, age);
8}
9
10int main() {
11 int year = 2024; // Local variable on STACK
12 char city[] = "NYC"; // Local array on STACK
13
14 greet("Alice", 25); // New stack frame created
15
16 // After greet() returns, its stack frame is removed
17 printf("Year: %d, City: %s\n", year, city);
18
19 return 0;
20}
Output

Hello Alice, you are 25 years old!

Year: 2024, City: NYC

📦 Stack Frame During greet() Call

greet() frame
name, age, message[50]
main() frame
year, city[]
... rest of stack ...

← When greet() returns, its frame is popped

08Stack vs Heap Comparison

FeatureStackHeap
GrowsDownward ↓Upward ↑
SpeedVery FastSlower
Managed ByCompiler (auto)Programmer (manual)
Size LimitSmall (1-8 MB)Large (RAM limited)
AllocationAutomaticmalloc()/free()
RiskStack OverflowMemory Leak

09Checking Segment Sizes (Linux)

On Linux, use the size command to see the size of each segment:

terminal
BASH
1# Compile the program
2gcc program.c -o program
3
4# Check segment sizes
5size program
6
7# Output example:
8# text data bss dec hex filename
9# 1418 544 8 1970 7b2 program

Experiment: Watch Segments Grow

Add Initialized Global

int score = 100;

→ Data segment grows

Add Uninitialized Global

int count;

→ BSS segment grows

10Complete Example: All Segments

all_segments.c
C
1#include <stdio.h>
2#include <stdlib.h>
3
4// DATA segment (initialized globals)
5int maxPlayers = 4;
6const char *version = "1.0";
7
8// BSS segment (uninitialized globals)
9int highScore;
10char playerName[20];
11
12void showInfo(int level) {
13 // STACK: level parameter, bonus local variable
14 int bonus = level * 100;
15 printf("Level %d bonus: %d\n", level, bonus);
16}
17
18int main() {
19 // STACK: local variables
20 int currentLevel = 5;
21
22 // HEAP: dynamic allocation
23 int *inventory = (int *)malloc(10 * sizeof(int));
24
25 printf("=== Memory Segments Demo ===\n");
26 printf("Max Players: %d (DATA)\n", maxPlayers);
27 printf("High Score: %d (BSS, auto=0)\n", highScore);
28
29 showInfo(currentLevel);
30
31 // Clean up heap
32 free(inventory);
33
34 return 0;
35}
Output

=== Memory Segments Demo ===

Max Players: 4 (DATA)

High Score: 0 (BSS, auto=0)

Level 5 bonus: 500

📍 Where Each Variable Lives

VariableSegmentWhy?
maxPlayersDATAGlobal, initialized
versionDATA (RO)String literal (const)
highScoreBSSGlobal, uninitialized
playerNameBSSGlobal array, uninitialized
currentLevelSTACKLocal to main()
level, bonusSTACKLocal to showInfo()
inventoryHEAPmalloc() allocated

11Summary

🎯 Key Takeaways

  • TEXT: Compiled code (read-only)
  • DATA: Initialized global/static variables
  • BSS: Uninitialized global/static (auto = 0)
  • HEAP: Dynamic memory (malloc), grows UP
  • STACK: Local variables, function calls, grows DOWN

int globalInit = 5;

int globalUninit;

int localVar = 10;

int *ptr = malloc(4);

09Next Steps

Learn about dynamic memory allocation: