Memory Layout in C

Memory layout means how your program’s code + data is arranged in memory while execution.

A typical C process memory is divided into segments:

High Address
+-----------------------------------------------+
| Stack                                         |
| - function calls (stack frames)               |
| - local variables                             |
| - return address                              |
+-----------------------------------------------+
| (gap/guard pages)                             |
+-----------------------------------------------+
| Heap                                          |
| - dynamic memory (malloc/calloc/realloc)      |
| - grows as requested                          |
+-----------------------------------------------+
| BSS                                           |
| - uninitialized globals/statics (zero)        |
+-----------------------------------------------+
| Data                                          |
| - initialized globals/statics                 |
+-----------------------------------------------+
| Text / Code                                   |
| - machine instructions                        |
| - read-only constants, string literals (.rodata)
+-----------------------------------------------+
Low Address

Stack grows downward (towards low addresses)
Heap grows upward (towards high addresses)

When heap and stack collide → memory exhausted / crash.


Memory Layout Diagram

Memory Layout

Shows how a C program is organized in memory into segments like text, data, bss, heap, and stack, including heap/stack growth direction.


1) Text Segment (Code Segment)

Example:

printf("Hello"); // "Hello" typically in read-only region

2) Data Segment

Stores global and static variables.

2.1 Initialized Data

int a = 10;        // global
static int b = 20; // static

These variables appear inside executable with their initial values.

2.2 Uninitialized Data (BSS)

int x;         // global uninitialized
static int y;  // static uninitialized

3) Heap Segment

Heap used for dynamic allocation.

Functions:

Heap key points


4) Stack Segment

Used for function execution.

A stack frame usually contains:

Why stack is fast?

Because stack allocation is just moving stack pointer.

Stack limitations


When is memory allocated? (important)


Quick experiment

#include <stdio.h>
#include <stdlib.h>

int g1 = 10;      // data
int g2;           // bss
static int s1=7;  // data

int main() {
    int local = 5;        // stack
    int *p = malloc(4);   // heap
    *p = 99;

    printf("&g1=%p\n", (void*)&g1);
    printf("&g2=%p\n", (void*)&g2);
    printf("&s1=%p\n", (void*)&s1);
    printf("&local=%p\n", (void*)&local);
    printf("heap p=%p\n", (void*)p);

    free(p);
}

Observe: stack addr usually higher than heap.


Tools (Linux)

size a.out
nm -S a.out | head
readelf -S a.out | less