Dynamic Memory (malloc/free)
Dynamic memory allocation allows you to request memory from the system heap at runtime. Because C does not have garbage collection, you must manage and free this memory manually.
1 Stack vs Heap & Memory Allocations
Static variables are stored on the **stack**, which is managed automatically by the compiler. Dynamic allocations exist on the **heap** and must be managed using the following standard library functions (`<stdlib.h>`):
- `malloc(size)`: Allocates a block of memory of the specified byte size. Leaves the allocated memory uninitialized (filled with random garbage values).
- `calloc(count, size)`: Allocates memory and automatically initializes all bytes to zero.
- `free(ptr)`: Releases the allocated memory block back to the system.
⚠️ Critical Safety Rules:
- Check for NULL: `malloc` returns `NULL` if the system runs out of memory. Always verify that pointers are not `NULL` before dereferencing.
- Memory Leaks: Failing to call `free()` on heap-allocated memory causes memory leaks, which consume system resources over time.
- Dangling Pointers: After calling `free(ptr)`, reset the pointer to `NULL` (`ptr = NULL;`) to prevent accidental reuse.
2 Dynamic Allocation Code
Let's run a program allocating a dynamic array of integers, initializing elements, and freeing memory safely:
C — Dynamic Allocation
▶ Run Code
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5;
// Allocate space for 5 integers
int *arr = (int*) malloc(n * sizeof(int));
// Always check for allocation failure
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Initialize array values
for (int i = 0; i < n; i++) {
arr[i] = (i + 1) * 10;
}
printf("Dynamic Array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Free the allocated memory to prevent leaks
free(arr);
arr = NULL; // Prevent dangling pointer usage
return 0;
}
3 Code Challenge
Challenge: Write a program that uses `calloc` to allocate memory for 3 double variables. Print the initial values to verify they are auto-initialized to `0.0`. Assign values to them, print them, and call `free()` to release the memory.