Memory Layout Tutorials
Programming
Memory Layout of C Programs
The memory layout of a C program describes how memory is organized during program execution.
When a C program runs, its memory is divided into different segments. Each segment stores a specific type of data.
Understanding memory layout helps developers:
Manage memory efficiently.
Improve program performance.
Debug memory-related issues.
Avoid segmentation faults and memory leaks.
Memory Layout of a C Program
A running C program is generally divided into the following memory segments:
Text Segment
Initialized Data Segment
Uninitialized Data Segment (BSS)
Heap Segment
Stack Segment
plaintextplaintext
Higher Memory Address
-------------------------
| Stack |
-------------------------
| |
| Free Memory |
| |
-------------------------
| Heap |
-------------------------
| BSS |
-------------------------
| Data Segment |
-------------------------
| Text Segment |
-------------------------
Lower Memory Address1. Text Segment (Code Segment)
The Text Segment stores the executable instructions of the program.
It contains:
Program code
Functions
Machine instructions
Characteristics
Usually read-only.
Prevents accidental modification of code.
Located in lower memory addresses.
Size depends on program complexity.
Example
plaintextplaintext
#include <stdio.h>
void display()
{
printf("Hello World");
}
int main()
{
display();
return 0;
}The machine code for main() and display() is stored in the Text Segment.
2. Data Segment
The Data Segment stores global and static variables.
These variables remain available throughout the entire execution of the program.
The Data Segment is divided into:
Initialized Data Segment
Uninitialized Data Segment (BSS)
A. Initialized Data Segment
This segment stores global and static variables that have been initialized by the programmer.
Example
plaintextplaintext
#include <stdio.h>
int globalVar = 10;
int main()
{
static int staticVar = 20;
printf("%d\n", globalVar);
printf("%d\n", staticVar);
return 0;
}Variables Stored Here
plaintextplaintext
int globalVar = 10;
static int staticVar = 20;Both variables are stored in the Initialized Data Segment.
B. Uninitialized Data Segment (BSS)
BSS stands for:
plaintextplaintext
Block Started by SymbolThis segment stores:
Uninitialized global variables
Uninitialized static variables
The operating system automatically initializes them to zero.
Example
plaintextplaintext
#include <stdio.h>
int globalVar;
int main()
{
static int staticVar;
printf("%d\n", globalVar);
printf("%d\n", staticVar);
return 0;
}Output
plaintextplaintext
0
0Variables Stored Here
plaintextplaintext
int globalVar;
static int staticVar;Both are stored in the BSS Segment.
Difference Between Data Segment and BSS
Initialized Data Segment
plaintextplaintext
int num = 100;
static int marks = 50;Variables have initial values.
BSS Segment
plaintextplaintext
int num;
static int marks;Variables are not initialized and automatically become zero.
3. Heap Segment
The Heap Segment is used for dynamic memory allocation.
Memory is allocated during runtime according to program requirements.
Functions Used
malloc()
calloc()
realloc()
free()
Characteristics
Shared by the entire program.
Grows towards higher memory addresses.
Managed by the programmer.
Example
plaintextplaintext
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
ptr = (int *)malloc(sizeof(int));
*ptr = 100;
printf("%d", *ptr);
free(ptr);
return 0;
}Output
plaintextplaintextCopy
100The memory allocated using malloc() is stored in the Heap Segment.
Heap Memory Leak
If dynamically allocated memory is not released using free(), a memory leak occurs.
Example
plaintextplaintext
int *ptr = (int *)malloc(sizeof(int));If free(ptr) is not called, memory remains occupied unnecessarily.
4. Stack Segment
The Stack Segment stores:
Local variables
Function parameters
Return addresses
Function call information
Every function call creates a Stack Frame.
Characteristics
Automatically managed by the compiler.
Grows towards lower memory addresses.
Faster than heap memory.
Example
plaintextplaintext
#include <stdio.h>
void display()
{
int localVar = 10;
}
int main()
{
display();
return 0;
}The variable:
plaintextplaintext
int localVar = 10;is stored in the Stack Segment.
Stack Frame
Each function call creates a separate stack frame.
Example
plaintextplaintext
void fun1()
{
int a = 10;
}
void fun2()
{
int b = 20;
}When fun1() is called:
plaintextplaintextCopy
Stack
------
a
------When fun2() is called:
plaintext
plaintext
Stack
------
b
------
a
------After function completion, the stack frame is automatically removed.
Stack Overflow
When too much memory is used on the stack, a Stack Overflow occurs.
Example
plaintextplaintext
void recursive()
{
recursive();
}Infinite recursion continuously creates stack frames until memory is exhausted.
Example Showing Different Memory Segments
plaintextplaintext
#include <stdio.h>
#include <stdlib.h>
int globalVar = 50;
void display()
{
int localVar = 10;
printf("%p\n", &localVar);
}
int main()
{
int *heapVar;
heapVar = (int *)malloc(sizeof(int));
display();
free(heapVar);
return 0;
}Memory Locations
plaintextplaintext
globalVar -> Data Segment
localVar -> Stack Segment
heapVar -> Heap Segment
display() -> Text SegmentMemory Layout Verification Example
plaintext
plaintext
#include <stdio.h>
#include <stdlib.h>
int globalVar = 100;
int uninitializedVar;
void display()
{
int localVar = 10;
printf("Address of localVar: %p\n",
(void *)&localVar);
}
int main()
{
int *heapVar =
(int *)malloc(sizeof(int));
printf("Address of display(): %p\n",
(void *)&display);
printf("Address of globalVar: %p\n",
(void *)&globalVar);
printf("Address of uninitializedVar: %p\n",
(void *)&uninitializedVar);
printf("Address of heapVar: %p\n",
(void *)heapVar);
display();
free(heapVar);
return 0;
}Sample Output
plaintextplaintext
Address of display(): 0x4011d0
Address of globalVar: 0x404020
Address of uninitializedVar: 0x404028
Address of heapVar: 0x119592a0
Address of localVar: 0x7ffe8289c66cThis demonstrates that different variables are stored in different memory segments.
Growth Direction of Heap and Stack
Heap
plaintextplaintext
Low Address
↑
↑
HeapHeap grows upward.
Stack
plaintextplaintext
Stack
↓
↓
High AddressStack grows downward.
What Happens When Heap Meets Stack?
If heap growth and stack growth collide, free memory is exhausted.
This may cause:
Program crash
Memory allocation failure
Stack overflow
Advantages of Understanding Memory Layout
Better memory management.
Easier debugging.
Prevents memory leaks.
Improves program performance.
Helps in system programming and embedded development.
Key Points
Text Segment stores program instructions.
Data Segment stores initialized global and static variables.
BSS Segment stores uninitialized global and static variables.
Heap is used for dynamic memory allocation.
Stack stores local variables and function call information.
Heap grows upward and stack grows downward.
Understanding memory layout helps avoid memory-related errors.
Summary
The memory of a C program is divided into several segments, including Text, Data, BSS, Heap, and Stack. Each segment serves a specific purpose. The Text Segment stores executable code, the Data and BSS Segments store global and static variables, the Heap manages dynamic memory allocation, and the Stack handles local variables and function calls. Understanding memory layout is essential for efficient memory management, debugging, and writing optimized C programs.