Dynamic Memory Allocation Tutorials
Programming
Dynamic Memory Allocation in C
Dynamic Memory Allocation (DMA) is a technique that allows memory to be allocated, resized, and released during program execution.
Unlike normal variables that are stored in the stack, dynamically allocated memory is stored in the heap and can be managed according to program requirements.
Why Do We Need Dynamic Memory Allocation?
In many situations, we do not know how much memory will be required before the program starts.
Dynamic Memory Allocation helps to:
Allocate memory at runtime.
Increase or decrease memory size when needed.
Efficiently use system memory.
Store data whose size is not known in advance.
Return memory from functions safely.
Heap Memory
Dynamic memory is allocated from the Heap Segment.
Characteristics of Heap Memory
Memory is allocated during runtime.
Managed by the programmer.
Remains available until explicitly released.
Shared across the entire program.
Dynamic Memory Functions
The following functions are available in the <stdlib.h> header file:
plaintext
malloc()
calloc()
realloc()
free()1. malloc() Function
malloc() stands for Memory Allocation.
It allocates a single block of memory at runtime.
Syntax
plaintext
ptr = (datatype *)malloc(size_in_bytes);Example
plaintext
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
ptr = (int *)malloc(sizeof(int) * 5);
for(int i = 0; i < 5; i++)
{
ptr[i] = i + 1;
}
for(int i = 0; i < 5; i++)
{
printf("%d ", ptr[i]);
}
free(ptr);
return 0;
}Output
plaintext
1 2 3 4 5Important Points About malloc()
Allocates memory from the heap.
Memory contains garbage values initially.
Returns a void pointer.
Returns NULL if allocation fails.
Checking Allocation Failure
Always verify whether memory allocation was successful.
plaintext
int *ptr = (int *)malloc(sizeof(int) * 5);
if(ptr == NULL)
{
printf("Memory Allocation Failed");
return 0;
}2. calloc() Function
calloc() stands for Contiguous Allocation.
It allocates memory for multiple elements and initializes all bytes to zero.
Syntax
plaintext
ptr = (datatype *)calloc(number_of_elements,
size_of_each_element);Example
plaintext
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
ptr = (int *)calloc(5, sizeof(int));
for(int i = 0; i < 5; i++)
{
printf("%d ", ptr[i]);
}
free(ptr);
return 0;
}Output
plaintext
0 0 0 0 0Difference Between malloc() and calloc()
malloc()
Allocates memory.
Memory contains garbage values.
Takes one argument.
Example:
plaintext
malloc(5 * sizeof(int));calloc()
Allocates memory.
Initializes memory with zero.
Takes two arguments.
Example:
plaintext
calloc(5, sizeof(int));3. free() Function
The free() function releases dynamically allocated memory back to the operating system.
Syntax
plaintext
free(pointer);Example
plaintext
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
ptr = (int *)malloc(sizeof(int));
*ptr = 100;
printf("%d\n", *ptr);
free(ptr);
return 0;
}Output
plaintext
100Best Practice After free()
After freeing memory, assign NULL to the pointer.
plaintext
free(ptr);
ptr = NULL;This prevents the pointer from becoming a dangling pointer.
Dangling Pointer
A pointer that points to memory that has already been freed is called a dangling pointer.
Example
plaintext
int *ptr;
ptr = (int *)malloc(sizeof(int));
free(ptr);
/* ptr is now dangling */Correct Way
plaintext
free(ptr);
ptr = NULL;4. realloc() Function
realloc() is used to resize an existing memory block.
It can:
Increase memory size.
Decrease memory size.
Syntax
plaintext
ptr = (datatype *)realloc(ptr, new_size);Example
plaintext
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
ptr = (int *)malloc(5 * sizeof(int));
ptr = (int *)realloc(ptr,
10 * sizeof(int));
free(ptr);
return 0;
}The memory block is expanded from 5 integers to 10 integers.
Safe Use of realloc()
Always use a temporary pointer.
plaintext
int *temp;
temp = (int *)realloc(ptr,
10 * sizeof(int));
if(temp != NULL)
{
ptr = temp;
}Why?
If realloc() fails:
plaintext
ptr = realloc(ptr, size);may lose the original memory block and create a memory leak.
Using a temporary pointer prevents this issue.
Practical Example
plaintext
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
ptr = (int *)malloc(5 * sizeof(int));
if(ptr == NULL)
{
printf("Allocation Failed");
return 0;
}
ptr = (int *)realloc(ptr,
8 * sizeof(int));
if(ptr == NULL)
{
printf("Reallocation Failed");
return 0;
}
for(int i = 0; i < 5; i++)
{
ptr[i] = (i + 1) * 10;
}
for(int i = 0; i < 5; i++)
{
printf("%d ", ptr[i]);
}
free(ptr);
return 0;
}Output
plaintext
10 20 30 40 50Memory Allocation Flow
plaintext
malloc()
↓
Use Memory
↓
realloc() (Optional)
↓
Use Memory
↓
free()Common Errors in Dynamic Memory Allocation
1. Memory Leak
Occurs when allocated memory is not released.
Wrong
plaintext
int *ptr;
ptr = (int *)malloc(sizeof(int));
/* free() not called */Correct
plaintext
free(ptr);2. Dangling Pointer
Occurs when memory is freed but pointer still stores the old address.
Wrong
plaintext
free(ptr);
printf("%d", *ptr);Correct
plaintext
free(ptr);
ptr = NULL;3. Allocation Failure
If memory is unavailable, allocation functions return NULL.
Example
plaintext
if(ptr == NULL)
{
printf("Allocation Failed");
}4. Memory Fragmentation
Repeated allocation and deallocation may create small unused memory blocks in the heap.
This can reduce memory efficiency over time.
Advantages of Dynamic Memory Allocation
Efficient memory utilization.
Memory allocated when needed.
Flexible data structures can be created.
Supports dynamic arrays.
Required for linked lists, stacks, queues, trees, and graphs.
Disadvantages of Dynamic Memory Allocation
Slower than stack allocation.
Programmer must manage memory manually.
Memory leaks may occur.
Dangling pointers may occur.
Memory fragmentation can happen.
Real-World Uses
Dynamic Memory Allocation is widely used in:
Dynamic Arrays
Linked Lists
Stacks
Queues
Trees
Graphs
Database Systems
Operating Systems
Summary
Dynamic Memory Allocation allows memory management during runtime.
Memory is allocated from the Heap Segment.malloc()allocates memory with garbage values.calloc()allocates memory initialized to zero.realloc()changes the size of an existing memory block.free()releases memory back to the system.
Always check for NULL and free allocated memory to avoid memory leaks.