Home

Memory Layout in C - Understanding Stack, Heap, and Segments

Understanding Memory Layout

Before you can master pointers or dynamic memory, you need to understand how memory is organized in a running C program. C gives you a level of control that few languages allow, but to use it safely, you must know where your data lives and how long it stays there.

The Memory Segments

When a program runs, its memory is divided into several key sections:

These segments are managed differently by the operating system, and each has a different lifetime and scope.

Tiny Code

Here’s a small program that prints the memory addresses of different variables to show where they live:


Code Example

Here is a simple C script to illustrate that point:

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

// Global variable (Data segment)
int global_var = 42;

// Uninitialized global variable (BSS segment)
int global_bss;

void show_addresses(void) {
    // Local variable (Stack)
    int local_var = 10;

    // Static variable (Data segment)
    static int static_var = 20;

    // Dynamic variable (Heap)
    int *heap_var = malloc(sizeof(int));
    *heap_var = 30;

    printf("Code (function) address:  %p\n", (void *)show_addresses);
    printf("Global variable address:  %p\n", (void *)&global_var);
    printf("Uninitialized global address:%p\n", (void *)&global_bss);
    printf("Static variable address:  %p\n", (void *)&static_var);
    printf("Stack variable address:   %p\n", (void *)&local_var);
    printf("Heap variable address:    %p\n", (void *)heap_var);

    free(heap_var);
}

int main(void) {
    show_addresses();
    return 0;
}

Output and Segment Details

Compile and run:

Code (function) address:  0x561ce7348169
Global variable address:  0x561ce7546014
Uninitialized global address:0x561ce7546018
Static variable address:  0x561ce7546020
Stack variable address:   0x7ffc94b65a5c
Heap variable address:    0x561ce774b2a0

Notice how the stack address is much higher than the heap, the stack usually grows downward, and the heap grows upward in memory.

How It All Works


Syntax explanation

printf("Code (function) address:        %p\n", (void *)show_addresses);
printf("Global variable address:        %p\n", (void *)&global_var);
printf("Uninitialized global address:   %p\n", (void *)&global_bss);
printf("Static variable address:        %p\n", (void *)&static_var);
printf("Stack variable address:         %p\n", (void *)&local_var);
printf("Heap variable address:          %p\n", (void *)heap_var);

This code is used to print the memory addresses of different types of variables and functions in C. It helps you visualize where different elements of your program live in the system’s memory layout (like the Stack, the Heap, or the Code segment).

Here is a breakdown of the syntax elements used in these lines.

  1. The %p Format Specifier
  1. The (void *) Cast
  1. The Address-of Operator (&)

Summary of Memory Segments Being Printed

Each line targets a completely different region of the program’s memory:


Diagram

High Addresses  0xFFFFFFFF
┌────────────────────────────────────────────────────────┐
│                        STACK                           │
│  grows DOWNWARD ↓ (Each new frame = lower address)     │
├────────────────────────────────────────────────────────┤
│                       │                                │
│                       ▼                                │
│                                                        │
│                       ▲                                │
│                       │                                │
├────────────────────────────────────────────────────────┤
│                        HEAP                            │
│  grows UPWARD ↑ (Each new malloc = higher address)     │
├────────────────────────────────────────────────────────┤
│                        BSS                             │
│  (Uninitialized global & static variables)             │
├────────────────────────────────────────────────────────┤
│                        DATA                            │
│  (Initialized global & static variables)               │
├────────────────────────────────────────────────────────┤
│                        TEXT                            │
│  (Compiled machine code instructions)                  │
└────────────────────────────────────────────────────────┘
Low Addresses   0x00000000
Tags: CLow-LevelProgramming