In C, a memory leak occurs when a program allocates memory dynamically (using functions like malloc or calloc) but fails to deallocate or release that memory when it is no longer needed. Memory leaks can lead to a gradual increase in memory usage by a program, potentially causing it to consume more and more memory until it crashes. Here are a few examples of memory leaks in C, along with explanations and suggestions for prevention:
Not Freeing Allocated Memory:
#include <stdlib.h>
int main() {
int *arr = (int *)malloc(5 * sizeof(int));
return 0;
}
Explanation: The malloc function is used to allocate memory for an integer array, but there's no corresponding call to free to release that memory.
Prevention: Always free dynamically allocated memory using the free function when it is no longer needed.
free(arr);
Forgetting to Free Memory in Loops:
#include <stdlib.h>
int main() {
for (int i = 0; i < 5; i++) {
int *arr = (int *)malloc(10 * sizeof(int));
}
return 0;
}
Explanation: Memory is allocated inside a loop, but it's not freed inside the loop, leading to multiple allocations without deallocation.
Prevention: Ensure that memory is freed inside the loop if it's no longer needed.
for (int i = 0; i < 5; i++) {
int *arr = (int *)malloc(10 * sizeof(int));
free(arr);
}
Lost Pointers:
#include <stdlib.h>
int *createArray() {
int *arr = (int *)malloc(5 * sizeof(int));
return arr;
}
int main() {
int *arr = createArray();
return 0;
}
Explanation: The pointer arr is returned from the function createArray, but there's no reference to it in main, and thus there's no way to free the allocated memory.
Prevention: Keep track of all dynamically allocated pointers and ensure that they are freed when no longer needed.
int *arr = createArray();
free(arr);
Conditional Memory Allocation without Corresponding Deallocation:
#include <stdlib.h>
void processInput(int size) {
int *arr;
if (size > 0) {
arr = (int *)malloc(size * sizeof(int));
}
}
int main() {
processInput(5);
processInput(0);
return 0;
}
Explanation: Memory is allocated conditionally based on the input size, but if the condition is not met, the allocated memory is not freed.
Prevention: Ensure that memory is freed in all possible code paths.
void processInput(int size) {
int *arr;
if (size > 0) {
arr = (int *)malloc(size * sizeof(int));
free(arr);
}
}
Overwriting Pointers without Freeing Memory:
#include <stdlib.h>
int main() {
int *arr = (int *)malloc(5 * sizeof(int));
arr = (int *)malloc(10 * sizeof(int));
return 0;
}
Explanation: The original memory allocated for arr is lost when a new allocation is made without freeing the previous memory.
Prevention: Free the previous memory before overwriting the pointer.
free(arr);
arr = (int *)malloc(10 * sizeof(int));
Dynamic Memory Allocation in Functions without Proper Deallocation:
#include <stdlib.h>
void allocateMemory(int **arr, int size) {
*arr = (int *)malloc(size * sizeof(int));
}
int main() {
int *arr;
allocateMemory(&arr, 5);
return 0;
}
Explanation: Memory is allocated in the allocateMemory function, but it's not freed before returning to the calling function.
Prevention: Free memory before returning from the function.
void allocateMemory(int **arr, int size) {
*arr = (int *)malloc(size * sizeof(int));
free(*arr);
}
Incomplete Deallocation in Multi-Dimensional Arrays:
#include <stdlib.h>
int main() {
int **matrix = (int **)malloc(3 * sizeof(int *));
for (int i = 0; i < 3; i++) {
matrix[i] = (int *)malloc(3 * sizeof(int));
}
free(matrix);
return 0;
}
Explanation: Although memory is allocated for rows of a 2D array, only the memory for the array of pointers is freed, not the memory for each row.
Prevention: Free the memory for each row before freeing the array of pointers.
for (int i = 0; i < 3; i++) {
free(matrix[i]);
}
free(matrix);
Memory Leak in Linked List Nodes:
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
int main() {
struct Node *head = (struct Node *)malloc(sizeof(struct Node));
return 0;
}
Explanation: Memory is allocated for the head of a linked list, but it's not freed before the program exits.
Prevention: Free the memory for each node in the linked list before the program exits.
free(head);
Memory Leak with strdup:
#include <stdlib.h>
#include <string.h>
int main() {
char *str = strdup("Memory Leak Example");
return 0;
}
Explanation: The strdup function allocates memory for a duplicated string, but the memory is not freed.
Prevention: Free the memory allocated by strdup using free.
free(str);
Memory Leak in a Function Using malloc:
#include <stdlib.h>
int *createArray(int size) {
int *arr = (int *)malloc(size * sizeof(int));
return arr;
}
int main() {
int *arr = createArray(5);
return 0;
}
Explanation: Memory is allocated in a function, but it's not freed after the function returns.
Prevention: Free the memory in the calling function when it is no longer needed.
free(arr);