Difference between delete & []delete and rise of Memory Leaks

Understanding difference between delete & []delete and rise of Memory Leaks

We are going to see why memory leaks happen when we mix delete and delete[ ]. We use the new[] operator to allocate memory dynamically on heap.

New[ ] funcion :

The new[ ] first allocates the memory on heap equivalent to the size of the object and then it calls the default constructor for the object.

While deleting the memory allocated by new[ ] operator we should not use delete operator especially when there are multiple objects. It is because delete operator calls the destructor of a single object only and the remaining objects destructors are not called even though the memory space is deallocated. This can cause memory leaks.

#include <iostream>
class Example
{
    int *ptr;

public:
    Example()
    {
        std::cout << "Example's Constructor\n";
        ptr = new int();
    }
    ~Example()
    {
        std::cout << "Example's Destructor\n";
        delete ptr;
        ptr = NULL;
    }
};
int main()
{
    Example *ptrArr = new Example[10];
    delete ptrArr;
    //When we delete the ptr here using delete
    //it only calls one destructor and it deallocates
    //all the memory however the remaining 9 objects
    //are not deleted.
    return 0;
}

Here 10 objects were allocated using new[ ] operator but as we used delete[ ] operator it deallocates all the memory, however the remaining 9 objects are not destructed resulting in memory leak.

Output :
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Destructor

How to fix this memory leak caused by mixing new[] and delete ?

To avoid the memory leak caused by the delete operator, we have to use delete[ ] which would delete the dynamically allocated heap memory.

The delete[ ] operator first call the destructor of each of the allocated object and then de-allocates the memory from the heap.

#include <iostream>
class Example
{
    int *ptr;

public:
    Example()
    {
        std::cout << "Example's Constructor\n";
        ptr = new int();
    }
    ~Example()
    {
        std::cout << "Example's Destructor\n";
        delete ptr;
        ptr = NULL;
    }
};
int main()
{
    Example *ptrArr = new Example[10];
    delete[] ptrArr;
    //When we delete the ptr here using delete[ ]
    //it deletes all the allocated objects while
    //also deallocating space preventing memory leak.
    return 0;
}
Output :
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Constructor
Example's Destructor
Example's Destructor
Example's Destructor
Example's Destructor
Example's Destructor
Example's Destructor
Example's Destructor
Example's Destructor
Example's Destructor
Example's Destructor