Memory Leaks in C


Reading time: 30 minutes | Coding time: 10 minutes

Before getting into Memory leaks we must be aware about Dynamic Memory Allocation and if you need to brush up,I'd recommend reading this article first Dynamic Memory Allocation.
A quick recap of concepts is here.
Inkedcodeschool_LI

The memory that is allocated for the execution of a program or we can say application memory is typically divided into these four segments.

  • One Section store the instructions that needs to be executed is called Code Segment or Text Degment.
  • Another Segment/Section is used to store the global variables,the variables that are not declared inside the function and have lifetime of whole application.
  • Another segment of memory is used for function calls and store all the local variables,this section is called STACK.
    The size of these 3 segment,i.e the Size Segment,Global Segment and the Stack are fixed and decided when the program is compiling i.e at the compile time.

And,the fourth section,which is called HEAP or Dynamic Section does not have fixed size.Heap can grow as per our need.As we know we get memory for the heap by making the call to malloc function in C and when we are done using the memory on the heap, we make a call to the free function to deallocate or free that particular memory.In C++ apart from malloc and free we can also use the operator new to get some memory and delete operator to free to delete that memory.

Memory Leak is a situation when we get some memory on the heap and do not free it when we are done using it.so our application is actully holding on to some unused memory in the heap, but why do we call it this situation Memory Leak and why does it happen due to improper use of dyanamic memory only, due to improper use of heap only and not some other section of application memory.

Memory leaks in C happen for three core reasons:

  • we do not free the memory that is no longer needed
  • we do try to free the memory but we do not have the reference to it (dangling pointer)
  • we try to free the memory using the wrong function

we will try to understand this through one simple program so what I'll do is write one simple program and show the simulation of its execution in the memory to explain these concepts.

#include <stdlib.h>
#include <stdio.h>
int main(void)
{ 
    char *line = NULL;
    size_t size = 0;
    /* The loop below leaks memory as fast as it can */
    for(;;) { 
        getline(&line, &size, stdin); /* New memory implicitly allocated */
        /* <do whatever> */
        line = NULL;
    }
    return 0;
 }

This is an example of a leak that will eventually exhaust available memory leak by calling getline(),a function that allocates new memory,without freeing that memory.

So, to avoid this we need to free the allocated memory to avoid leaking.

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
    char *line = NULL;
    size_t size = 0;
    for(;;) {
        if (getline(&line, &size, stdin) < 0) {
            free(line);
            line = NULL;
            /* Handle failure such as setting flag, breaking out of loop and/or exiting */
        }
        /* <do whatever> */
        free(line);
        line = NULL;
    }
    return 0;
}

Example of dangling pointer:

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
    char *data1 = "opengenus";
    char *data2 = "new_data";
    data2 = data1; // both data1 and data2 point to the same memory
    free(data1); 
    free(data2); // does not free original data2
    return 0;
}

In this example, we have lost the original reference to the memory for data2 due to which we cannot deallocate it.

Types of Memory Leaks or Common Dynamic Memory Problems in C are:

  • Dynamic memory allocation malloc and not deallocating it.
  • Dynamic memory allocation malloc and deallocate it with delete.
  • Dynamic memory allocation with new and not deallocating with delete.
  • Dynamic memory allocation with new[ ] and deallocating with delete.
  • Dynamic memory allocation new and deallocate it with free.

Let's discuss them in brief-

Dynamic memory allocation malloc and not deallocating it.

Liked we discussed earlier we allocated Dynamic memory and never deallocated it.This leads to memory leaks.
We should always deallocate the memory which is Dynamically allocated otherwise the program will consume memory until it is shut down.
Whenever you allocate Dynamic memory using malloc and never dealllocated it go to Task manager and look at the memory consumption which will be increasing as long as your program is running.
Therefore,it is very important to deallocate the memory which is Dynamically allocated to avoid such situationns.

Dynamic memory allocation malloc and deallocate it with delete

As we all know that malloc is used to allocate dynamic memory in C,and we need to free this memory to avoid memory leak but sometimes instead of using free()
we use delete keyword to free this memory which is used in C++ to free Dynamic memory.

Here is an example:

ptr = (int*) malloc(100 * sizeof(int));
delete ptr; // free(ptr) should be used in order to deallocate dynamic memory

Dynamic memory allocation with new and not deallocating with delete

Dynamic Memory allocation in c++ is done using new

pointer-variable = new data-type(value);

Example:

int *p = new int(25);

To deallocate Dynamic memory in c++ we need to use delete but most of the time we forgot to deallocate the memory which causes Memory leaks.

delete p;

delete operator is used to deallocate Dynamic memory allocated in c++.

Dynamic memory allocation with new[ ] and deallocating with delete

int *p = new int[10];

Dynamically allocates memory for 10 integers continuously of type int and returns pointer to the first element of the sequence, which is assigned to p(a pointer). p[0] refers to first element, p[1] refers to second element and so on.

To free up Dynamic memory allocated to an array we cannot directly use delete operator.

// Release block of memory 
// pointed by pointer-variable
delete[] pointer-variable;  

This will free the entire array and there will be no Memory leaks.

Dynamic memory allocation new and deallocate it with free.

Till now we have understood that we need to deallocate the memory which we have dynamically allocated but what if deallocate the memory using different keyword i.e what if we deallocate using free() operator in C++ and delete in C.

The memory won't be deallocated or the space won't be free using these keywords if not used properly.

  • free() operator is used in C to deallocate dynamic memory.
  • delete operator is used in C++ to deallocate dynamic memory.

So, finally to summerize it, Memory Leak is improper use of dynamic memory or the heap section of the memory that causes the memory consumption of our program to increase over a period of time.

Remember Memory Leak always happens because of unused and unreferenced memory blocks in the heap. Anything on the stack is deallocated automatically and stack is always fixed in size.At the most we can have an overflow in the stack.