new & delete operators in C++

C++ provides the new and delete operators for memory management. We can use,

  • The new operator to dynamically allocate the memory from heap.
  • The delete operator to deallocate the memory back to heap.

In comparision to the traditional C-style memory management functions, the new and delete operators provide a secure & object oriented way to manage memory.

The ‘new’ Operator

The new operator in C++ is used to allocate memory on the heap for an object or an array of objects. Then it also initalzes these allocated objects. There is no need to provide the size of memory while dynamcally allocation memory on heap using the new() operator. It automatically calculates the size of the data object from its type information. Also, the new operator initializes the memory to zero, and then calls the constructor wth given arguments.

Here’s a basic syntax of new:

TYPE * ptr = new TYPE;

It will allocate a memory on heap equvalent to the size of given Data Type i.e. TYPE. It can be an int, char, double or any other data type. Let’s see an example,

int * ptr = new int;

In the above statement, the new operator dynamically allocates memory for an integer and returns a pointer to that memory. This pointer is then stored in an integer ponter ptr. As the size of integer is 4, so it will allocate 4 bytes on the heap and intialzes it with value 0. The new operator returns the address of the allocated memory and we initialized our pointer ptr with that.

Now we can access the value at this memory by derefrencng the pointer i.e.



    std::cout<< *ptr ;
    

    Output:

    0
    

    By default, the new operator intialzes the allocated memory with 0, therefore when we accessed the data at the allocated memory using pointer ptr, it returned 0. If you want to initalze the memory with a given value, then can pass it as argument while calling the new operator i.e.

    int * ptr2 = new int(11);
    

    The new operator here allocated 4 bytes on heap and intialzed it with value 11. When we provide a value as an argument while calling the new operator then it calls the constructor of that object after allocated the memory on heap. In the constructor, it will pass the given value to initialize the object. If we don’t provide any value as an argument in the new operator, then it will initialze the memory with 0.

    The new operator returns the address of the allocated & intialzed memory and we initialized our pointer ptr2 with it.

    Now we can access the value at this memory by derefrencng the pointer i.e.

    std::cout<< *ptr2 ;
    

    Output:

    11
    

    Here we used the pointer ptr2 to access the value at the allocated memory. We can also change the value at that memory location using the pointer. Like this,

    *ptr2 = 22;
    
    std::cout<< *ptr2 ;
    

    Output:

    22
    

    Here, using a pointer we changed the value from 11 to 22.

    Instead of allocated a memory for an integer on heap, we can also allocate a double on heap. In this case it will allocate 8 byes on heap.

    double * ptr3 = new double(99.9); 
    

    It will allocate 8 bytes on heap, because the size of double is 8 bytes. Then it will call the constrcutor of double and initialze the memory with value 99.9. It returns a pointer to the allocated memory on the heap. We initiazed a pointer to double i.e. ptr3 with the returned addreess of memory.

    We can access the double value at the memory on heap, by derefrencing the pointer pointing to it i.e. ptr3.

    std::cout<< *ptr3 ; 
    

    Output:

    99.9
    

    Important Point:

    The new operator will throw an exception (std::bad_alloc) if it is not able to allocate the requested memory.

    The complete example,

    #include <iostream>
    
    int main() 
    {
        try 
        {
            int* ptr = new int;
    
            // Assign a value to the 
            // allocated memory
            *ptr = 10;
            std::cout << "Value of integer: " << *ptr << '\n';
        } 
        catch (const std::bad_alloc& e) 
        {
            std::cerr << "Memory allocation failed: " << e.what() << '\n';
            return 1;
        }
    
        return 0;
    }
    

    Output:

    Value of integer: 10
    

    In this program, we allocated memory for an integer on heap and then accessed it. But we never de-allocated that memory, therefore it is a kind of Memory Leak.

    Till now we have learned how to allocate memory on heap using the new operator. But once memory is allocated on heap, then after some time, when it is not requied, we must deallocate the memory on heap, otherwise it can result in memory leak. So, let’s dicsuss how to delete allocated memory using the delete operator in C++.

    The ‘delete’ Operator

    The delete operator is used to deallocate memory that was previously allocated with new operator in C++. The delete operator also calls the destructor for the object before deallocation the memery.

    Here’s a basic syntax of delete:

    delete ptr;
    

    In this case, the delete operator deallocates the memory pointed to by ptr. But before callng the delete operator, we need to be sure that pointer ptr is pointing to a memory that was dynamically allocated on heap using the new operator.

    The complete example,

    #include <iostream>
    
    int main() 
    {
        try 
        {
            int* ptr = new int;
    
            // Assign a value to the 
            // allocated memory
            *ptr = 10;
            std::cout << "Value of integer: " << *ptr << '\n';
    
            delete ptr;
            ptr = nullptr;
        } 
        catch (const std::bad_alloc& e) 
        {
            std::cerr << "Memory allocation failed: " << e.what() << '\n';
            return 1;
        }
    
        return 0;
    }
    
    

    Output:

    Value of integer: 10
    

    new & delete in C++ vs malloc(), calloc() & free() in C

    The new and delete operators in C++ offer many advantages over the old C-style functions malloc(), calloc(), realloc(), and free(). Let’s discuss them one by one,

    • Type Safety:

      The new and delete operators are type-safe. They return the correct pointer type, so there is no need to cast the returned pointer. Where as, the malloc() or calloc() returns a void pointer, and you need to cast it to appropriate type of pointer. This increases the chances of mistake.

    • Object Construction and Destruction:

      Unlike malloc() and free() functions, the new & delete operators calls the constructor and destructor of allocated & deallocated objects.

    • Operator Overloading:

      The new and delete operators can be overloaded in C++, which allows programmers to define custom behaviour for memory allocation and deallocation.

    • Exception Handling:

      The new operator throws an exception (std::bad_alloc) if it cannot allocate the requested memory, whereas malloc() simply returns a null pointer.

    Summary

    C++ supports C-style memory management functions too, but it is recommended to use new and delete in C++ for memory management. It will give your application more safety, ease of maintenance, and consistency with the language’s object-oriented features.

    Scroll to Top