# Memory leaks can leave you broke!

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:

1. **Not Freeing Allocated Memory:**
    
    ```c
    #include <stdlib.h>
    
    int main() {
        int *arr = (int *)malloc(5 * sizeof(int));
        // Some code using arr
        // Memory should be freed, but it's not.
        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.
    
    ```c
    free(arr);
    ```
    
2. **Forgetting to Free Memory in Loops:**
    
    ```c
    #include <stdlib.h>
    
    int main() {
        for (int i = 0; i < 5; i++) {
            int *arr = (int *)malloc(10 * sizeof(int));
            // Some code using arr
            // Memory is not freed in each iteration
        }
        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.
    
    ```c
    for (int i = 0; i < 5; i++) {
        int *arr = (int *)malloc(10 * sizeof(int));
        // Some code using arr
        free(arr); // Free the memory before the next iteration
    }
    ```
    
3. **Lost Pointers:**
    
    ```c
    #include <stdlib.h>
    
    int *createArray() {
        int *arr = (int *)malloc(5 * sizeof(int));
        // Some code using arr
        return arr; // Memory is returned but not freed
    }
    
    int main() {
        int *arr = createArray();
        // Memory is lost since there's no reference to it and no way to free it.
        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.
    
    ```c
    int *arr = createArray();
    // Some code using arr
    free(arr); // Free the memory when done using it
    ```
    
4. **Conditional Memory Allocation without Corresponding Deallocation:**
    
    ```c
    #include <stdlib.h>
    
    void processInput(int size) {
        int *arr;
        if (size > 0) {
            arr = (int *)malloc(size * sizeof(int));
            // Some code using arr
        }
        // Memory is not freed if size <= 0
    }
    
    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.
    
    ```c
    void processInput(int size) {
        int *arr;
        if (size > 0) {
            arr = (int *)malloc(size * sizeof(int));
            // Some code using arr
            free(arr); // Free memory when size > 0
        }
        // No memory to free if size <= 0
    }
    ```
    
5. **Overwriting Pointers without Freeing Memory:**
    
    ```c
    #include <stdlib.h>
    
    int main() {
        int *arr = (int *)malloc(5 * sizeof(int));
        // Some code using arr
        arr = (int *)malloc(10 * sizeof(int)); // Overwriting the pointer without freeing the previous memory
        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.
    
    ```c
    free(arr); // Free the original memory
    arr = (int *)malloc(10 * sizeof(int)); // Allocate new memory
    ```
    
6. **Dynamic Memory Allocation in Functions without Proper Deallocation:**
    
    ```c
    #include <stdlib.h>
    
    void allocateMemory(int **arr, int size) {
        *arr = (int *)malloc(size * sizeof(int));
        // Some code using *arr
        // Memory is not freed before returning from the function
    }
    
    int main() {
        int *arr;
        allocateMemory(&arr, 5);
        // Memory is not freed after using arr
        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.
    
    ```c
    void allocateMemory(int **arr, int size) {
        *arr = (int *)malloc(size * sizeof(int));
        // Some code using *arr
        free(*arr); // Free memory before returning
    }
    ```
    
7. **Incomplete Deallocation in Multi-Dimensional Arrays:**
    
    ```c
    #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));
            // Some code using matrix[i]
        }
    
        // Memory is not freed properly for the rows
        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.
    
    ```c
    for (int i = 0; i < 3; i++) {
        free(matrix[i]); // Free memory for each row
    }
    free(matrix); // Free the array of pointers
    ```
    
8. **Memory Leak in Linked List Nodes:**
    
    ```c
    #include <stdlib.h>
    
    struct Node {
        int data;
        struct Node *next;
    };
    
    int main() {
        struct Node *head = (struct Node *)malloc(sizeof(struct Node));
        // Some code using head
        // Memory is not freed for head
        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.
    
    ```c
    free(head); // Free memory for the head node
    ```
    
9. **Memory Leak with** `strdup`:
    
    ```c
    #include <stdlib.h>
    #include <string.h>
    
    int main() {
        char *str = strdup("Memory Leak Example");
        // Some code using str
        // Memory is not freed for str
        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`.
    
    ```c
    free(str); // Free memory allocated by strdup
    ```
    
10. **Memory Leak in a Function Using** `malloc`:
    
    ```c
    #include <stdlib.h>
    
    int *createArray(int size) {
        int *arr = (int *)malloc(size * sizeof(int));
        // Some code using arr
        return arr;
    }
    
    int main() {
        int *arr = createArray(5);
        // Memory is not freed for arr
        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.
    
    ```c
    free(arr); // Free memory in the calling function
    ```
    

To prevent memory leaks in C:

* Always pair dynamic memory allocation (`malloc`, `calloc`, `realloc`) with corresponding deallocation (`free`).
    
* Free memory as soon as it is no longer needed.
    
* Be cautious with pointers returned from functions, and ensure you have a plan for releasing the associated memory.
    
* Use tools like `valgrind` to detect memory leaks and other memory-related issues in your C programs.
