Dynamic Memory in C/C++
Keywords
malloc: Allocates size of bytes of uninitialized (the object has not been given a known value) storage.
Declaration for malloc() function:
void *malloc(size_t size)
free: Deallocates the memory previously allocated by a call to calloc, malloc, or realloc.
Example using malloc and free below:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = malloc(100*sizeof(int));
free(p);
}
calloc: Allocates a specific amount of memory and initializes it to zero.
Declaration for calloc() function:
void *calloc(size_t nitems, size_t size)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = calloc(100, sizeof(int));
free(p);
}
Difference between malloc and calloc
malloc() | calloc() |
---|---|
malloc() function creates a single block of memory of a specific size. | calloc() function assigns multiple blocks of memory to a single variable. |
The number of arguments in malloc() is 1. | The number of arguments in calloc() is 2. |
malloc() is faster. | calloc() is slower. |
malloc() has high time efficiency. | calloc() has low time efficiency. |
The memory block allocated by malloc() has a garbage value. | The memory block allocated by calloc() is initialized by zero. |
malloc() indicates memory allocation. | calloc() indicates contiguous allocation. |
realloc: Reallocates the given area of memory. It must be previously allocated by malloc(), calloc() or realloc() and not yet freed with a call to free or realloc
void *realloc( void *ptr, size_t new_size );
Notes on Dynamic Memory
Code Examaples using malloc
Program using malloc to allocate memory and show location/addresses of where the memory is located at.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int *p1 = malloc(sizeof(int));
char *p2 = malloc(sizeof(char));
char *p3 = malloc(sizeof(char));
int *p4 = malloc(4 * sizeof(int));
int *p5 = malloc(1);
printf("p1 = %p\n", p1);
printf("p2 = %p\n", p2);
printf("p3 = %p\n", p3);
printf("p4 = %p\n", p4);
printf("p5 = %p\n", p5);
return 0;
}
Output:
p1 = 0x6000030cc000
p2 = 0x6000030cc010
p3 = 0x6000030cc020
p4 = 0x6000030cc030
p5 = 0x6000030cc040
Code Examaples using malloc, calloc and realloc
Program using malloc, calloc, and realloc to allocate memory. Prining out memory address and values.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void print_mem(int *p, int size) {
int i;
for (i = 0; i < size; ++i) {
printf("addr: %p | value: %x\n", p, *p);
++p;
}
printf("\n");
}
int main(int argc, char *argv[]) {
int *p1 = malloc(5 * sizeof(int));
int *p2 = calloc(5, sizeof(int));
printf("p1 = %p\n", p1);
printf("p2 = %p\n", p2);
print_mem(p1, 5);
print_mem(p2, 5);
p1 = realloc(p1, 5);
p2 = realloc(p2, 5);
printf("p1 = %p\n", p1);
printf("p2 = %p\n", p2);
print_mem(p1, 5);
print_mem(p2, 5);
return 0;
}
Output:
p1 = 0x12de069e0
p2 = 0x12de06a00
addr: 0x12de069e0 | value: 0
addr: 0x12de069e4 | value: 0
addr: 0x12de069e8 | value: 0
addr: 0x12de069ec | value: 0
addr: 0x12de069f0 | value: 0
addr: 0x12de06a00 | value: 0
addr: 0x12de06a04 | value: 0
addr: 0x12de06a08 | value: 0
addr: 0x12de06a0c | value: 0
addr: 0x12de06a10 | value: 0
p1 = 0x12de069e0
p2 = 0x12de06a00
addr: 0x12de069e0 | value: 0
addr: 0x12de069e4 | value: 0
addr: 0x12de069e8 | value: 0
addr: 0x12de069ec | value: 0
addr: 0x12de069f0 | value: 12de06a1
addr: 0x12de06a00 | value: 0
addr: 0x12de06a04 | value: 0
addr: 0x12de06a08 | value: 0
addr: 0x12de06a0c | value: 0
addr: 0x12de06a10 | value: 0
Notes on Memory Allocator Implementation
Memory Allocator: Manages the Memory in the heap.
How do we build a Memory Allocator? (What are the requirements)
- Only use the heap to manage the heap
- No modification of allocated blocks
- No re-ording of requests (of memory)
Goals of a Memory Allocator:
- Speed, Performance and Memory Utilization (reuse of free memory)
Fragmentation: As Processes are loaded and removed from memory, the free memory space is broken into little pieces (as you build programs and free blocks). It happens after sometimes that processes cannot be allocated to memory blocks considering their small size and memory blocks remains unsued. This sort of problem is known as Fragmentation.
There are two types of Fragmentation; External Fragmentation and Internal Fragmentation. More notes here on GeeksforGeeks.com.
Implementation of Fragmentation
Structure of a Heap Block