So far, all variables and arrays used fixed memory sizes determined during compilation. However, in many situations, the required memory size may not be known in advance. In such cases, C provides Dynamic Memory Allocation, which allows memory to be allocated and released during program execution.
Dynamic memory allocation is performed using functions from the <stdlib.h> library.
Why Dynamic Memory Allocation?
Dynamic memory allocation allows programs to:
- Allocate memory only when needed
- Efficiently manage memory usage
- Create variable-sized data structures
- Release unused memory during runtime
Unlike local variables stored on the Stack, dynamically allocated memory is obtained from the Heap region.
| Feature | Static Allocation | Dynamic Allocation |
|---|---|---|
| Memory Region | Stack Segment | Heap Segment |
| Timing | Compile-time | Runtime |
| Flexibility | Fixed size | Can grow / shrink |
1. malloc()
The malloc() (Memory Allocation) function reserves a single contiguous block of memory of a specified byte count. It returns a generic void* pointer to the first byte, which must be typecasted.
Syntax
// reserves X bytes without initializing contents
pointer = (type *) malloc(size_in_bytes);
Detailed Code Example
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
// Allocate space for 5 integers
ptr = (int *)malloc(5 * sizeof(int));
// Check if allocation succeeded
if (ptr == NULL) {
printf("Memory allocation failed");
return 1;
}
printf("Memory allocated successfully");
// Always free dynamic memory!
free(ptr);
return 0;
}
How It Works
- →
malloc()allocates memory from the Heap - →
sizeof(int)calculates the size of one integer - →
malloc(5 * sizeof(int))allocates memory for 5 integers - →
ptrstores the starting address of the allocated memory block - →
free()releases the allocated memory back to the system
2. calloc()
The calloc() function allocates memory for multiple elements and automatically initializes all bytes to zero.
Syntax
pointer = (type *) calloc(number_of_elements, size);
Example
ptr = (int *) calloc(5, sizeof(int));
3. realloc()
The realloc() function changes the size of previously allocated memory.
Syntax
pointer = (type *) realloc(pointer, new_size);
Example
ptr = (int *) realloc(ptr, 10 * sizeof(int));
4. free()
The free() function releases dynamically allocated memory when it is no longer needed.
Syntax
free(pointer);
Failing to free unused memory may result in memory leaks.
Heap Memory Concept
Unlike local variables stored on the Stack, dynamically allocated memory is created inside the Heap region during program execution. Functions such as malloc() and calloc() request memory from the Heap and return the starting address of the allocated block through a pointer. This memory remains allocated until it is explicitly released using free(). Since Heap memory is managed manually by the programmer, failing to release unused memory can lead to memory leaks and unstable program behavior.
Important Points
- → Dynamic memory is allocated from the Heap
- →
malloc()does not initialize memory - →
calloc()initializes allocated memory to zero - →
realloc()resizes previously allocated memory - →
free()should always be used to release unused memory - → Dynamically allocated memory is accessed using pointers
Embedded Focus
Dynamic memory allocation is used carefully in embedded systems because Heap memory is limited and fragmentation can affect long-term system stability. Many real-time systems avoid excessive dynamic allocation to maintain deterministic execution behavior.
// Allocating dynamic buffer for payload data
int *buffer = (int *)malloc(128 * sizeof(int));
Dynamic allocation is commonly used for communication buffers, protocol packets, runtime data structures, and variable-sized memory requirements.