Memory Leaks and Dangling Pointers in C++

Debajyoti Chatterjee
3 min readJan 23, 2021

DYNAMIC MEMORY ALLOCATION IN A CLASS

If we have a class where we are using DYNAMIC Memory Allocation in order to allocate memory (e.g. : for an Integer array) , then we must :

  • Have a DESTRUCTOR in order to de-allocate the memory in the heap once we are finished using the memory.
  • Overload the default COPY CONSTRUCTOR and the ASSIGNMENT operator in order to prevent side-effects caused by Shallow copying.

If not done, then it might lead to:

  • Memory leaks
  • Dangling pointers

Example 1 : Memory Leak due to a missing class Destructor

Figure 1 : Class Definition : “SimpleVector” class
Figure 2 : Call to the “process” method from the “main()” function is done in a for-loop
Figure 3: The call to the “process ()” method would cause a memory leak in case a Destructor for the class “SimpleVector” is not defined

When the control enters the “process ()” method after getting called by the “main ()”, the following allocation occurs:

  • STACK : int *item, numElements, size
  • HEAP : the actual array of size = size (Memory = 4 * size bytes considering that each integer is of size 4 bytes).

When the control comes out of the “process ()” method, the memory on the stack is freed up automatically. If there is no destructor called during the exit from the “process ()” method, then the actual array on the HEAP is unreferenced by any pointer now. This causes a memory leak of 4*size bytes.

If the call to the “process()” method from the “main()” function occurs multiple times using a loop as shown in the Figure (2) above, then we would have a memory leak of 4*size*No. of iterations bytes. If No. of Iterations is large, then this might cause the application to crash.

Example 2 : Memory leak due to Shallow Copying done by the Default Assignment operator

The default Assignment operator copies each attribute of one object to the other.

sv11 = sv10 ; //Invoked as sv11.operator=(sv10);

But at first let’s focus on the declaration of the objects sv10 and sv11 of the SimpleVector class.

Figure 4: Declaration of the “SimpleVector” type objects “sv10” and “sv11”
Figure 5: Memory Diagram that shows the regions in memory where the allocation has been done as a result of the code in the Figure 4 above
Figure 6: Shallow copying done by the Default Assignment operator
Figure 7: Memory diagram after the assignment operation is done using the Default Assignment operator

Example 3 : Dangling Pointers created due to the Default Copy Constructor when used for classes having dynamically allocated Memory for variables

We assume now that we have a destructor which deallocates the dynamically allocated memory upon invocation.

//Destructor for the Simple-Vector class
SimpleVector::~SimpleVector()
{
delete[] item;
std::cout << “SimpleVector Class :: Destructor called “ << std::endl;
}//~SimpleVector()

Figure 8 : Call to the “example_copy_constructor_problem ()” function from the “main()” function
Figure 9 : Dangling pointers are created since the Destructor is invoked once the program control exits this method and returns back to the “main” function
Figure 10 : “sv_11. item” and “sv10.item“ shall be Dangling pointers once the control returns to the “main ()” method since the memory for the array in the HEAP is de-allocated by the destructor

Once the control comes out of the method “example_copy_constructor_problem ()” and returns back to the “main()” function, we are left with 2 dangling pointers namely sv10.item and sv11.item.

--

--

Debajyoti Chatterjee

I am an engineer passionate about embedded systems and autonomous driving functions