Skip to main content

Command Palette

Search for a command to run...

Memory Layout of C Programs

Updated
5 min read
Memory Layout of C Programs
D

I'm an Engineer


When a C program is compiled and run, it`s memory is divided into well defined segments. Understanding these segments is essential for debugging, optimizing and avoiding subtle bugs like buffer overflow and segmentation faults.

In this post, we’ll break down the memory layout of a C program and provide examples for each segment.


Overview of Memory Segments

A C program`s memory is typically divided into the following segments:

  1. Text Segment (Code Segment)

  2. Initialized Data Segment

  3. Uninitialized Data Segment (BSS)

  4. Heap Segment

  5. Stack Segment

Let`s explore each segment with code examples.


1. Text Segment (Code Segment)

The text segment (also known as code segment) contains the machine compiled instructions of the program. It is typically read-only to prevent any accidental modifications to it.

#include <stdio.h>

int main() {
    return 0;
}

Output:

$ gcc -o memory_layout memory_layout.c 
$ size memory_layout
   text       data        bss        dec        hex    filename
   1228        544          8       1780        6f4    memory_layout
textSize (in bytes) of the text segment which includes all the compiled code. In this case, 1228 bytes are used for instructions
dataSize of initialized data segment. Although, there is no data initiaized in the code, the value 544 bytes comes from data initialzed from linked libraries, especially libc
bssSize of uninitialized data segment. Although, there is no data initiaized in the code, the value 8 bytes comes from data initialzed from linked libraries, especially libc
decTotal size in decimal 1228 + 544 + 8 = 1780 bytes
hexSame value as decimal in hexadecimal
filenameThe name of the compiled binary file

2. Initialized Data Segment

As the name suggests, this segment store global and static variables with explicit intial values that has been initialized in the program.

#include <stdio.h>

int global_var = 10;
static int static_var = 20;

int main() {
    return 0;
}

Output:

$ gcc -o memory_layout memory_layout.c 
$ size memory_layout
   text       data        bss        dec        hex    filename
   1228        552          8       1788        6fc    memory_layout

As seen in the output above: the data segment (initialized data segment) has increased from 544 bytes to 552 bytes whereas the bss segment value remains the same.


3. Uninitialized Data Segment (BSS)

Uninitialized data segment also known as BSS (Block Started by Symbol) contains global and static variables that has not been initialized in the program. These variables are automatically initialized to zero at runtime by the operating system.

#include <stdio.h>

int global_var;
static int static_var;

int main() {
    return 0;
}

Output:

$ gcc -o memory_layout memory_layout.c 
$ size memory_layout
   text       data        bss        dec        hex    filename
   1228        544         16       1788        6fc    memory_layout

As seen in the output above: the bss segment has increased from 8 bytes to 16 bytes whereas the data segment (initialized data segment) value remains the same.


4. Heap Segment

Heap segment is used where dynamic memory allocation takes place using malloc(), calloc(), realloc() etc.

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

int main() {
    int* heap_var = (int*)malloc(10 * sizeof(int));
    *heap_var = 10;
    printf("Heap Var = %d\n", *heap_var);
    free(heap_var);
    return 0;
}

Output:

$ gcc -o memory_layout memory_layout.c 
$ ./memory_layout 
Heap Var = 10

5. Stack Segment

Stack segment is responsible for storing local variables, function addresses and function parameters. Each time a function is called, a stack frame is created to store local variables, function parameters and return addresses.

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

void stack_function() {
    int local_variable = 42; // Local variable stored on the stack
    printf("Local variable value: %d\n", local_variable);
}

int main() {
    stack_function();
    return 0;
}

Output:

$ gcc -o memory_layout memory_layout.c 
$ ./memory_layout 
Local variable value: 42

Common Pitfalls

Understanding how improper use of memory segments can lead to bugs is crucial. Below are some typical pitfalls explained in detail:

1. Stack Overflow

The stack has a fixed size limit (usually few MB on most systems). When a program exceeds this limit, a stack overflow occurs resulting in a segmentation fault.

This commonly happens due to:

  • Infinite recursion

  • Allocating large arrays as local variables

void recurse() {
    int big_array[100000]; // ~400KB stack allocation
    recurse();             // no base case, causes infinite recursion
}

Each call to recurse() allocates a new frame on the stack. As there is no termination condition, the stack keeps growing until it runs out of space.


2. Memory Leak

A memory leak occurs when a program allocates memory on the heap and fails to release it using it free(). This leads to memory being reserved but never resused, eventually exhausting the system`s memory.

int* ptr = (int*)malloc(100); // dynamically allocates 100 bytes
// forgot free(ptr);    // memory is never released

In the above code, 100 bytes of memory is allocated on the heap , Since free(ptr) is never called the memory remains reserved until the program exits.


3. Dangling Pointer

A dangling pointer is a pointer which continues to reference a memory location after it has been freed or deallocated. Accessing a memory location through such a pointer results in undefined behavior - it may crash your program or corrupt data.

int* ptr = (int*)malloc(sizeof(int));
free(ptr);
ptr = NULL: // right way of deallocating
*ptr = 10; // undefined behavior : accessing freed memory

In the above code, memory is allocated for int, free(ptr) deallocates the memory. But ptr still points to invalid memory.


Conclusion

Understanding memory layour helps:

  • write safer code

  • avoid bugs

  • optimize embedded systems


46 views

More from this blog

The Engineering Hub

11 posts

knowledge sharing portal...