delete vs delete[] vs free in C++


In this article, we will explore the difference between delete, delete[], free keywords of C++ which are often confused with each other and sometimes wrongly used leading to the errors in one's program.

In short, all the three keywords (delete, delete[] and free)are used to deallocate or free a block of memory which had been allocated dynamically. We need to deallocate a block of memory to prevent memory leakage and crashing of the program in future.

Before we go into the differences between them, let us first get the basic understanding of the three keywords separately.

The free keyword

free is a pre-defined function, defined in 'cstdlib' header file of C++, which is used to deallocate a block of memory that was previously dynamically allocated using malloc, calloc, or realloc in case of reallocation of memory. This is done to make the memory available for future allocations.
The syntax of the free function is as follows:

void free(void *memory_block);

In the above code, memory_block is the previously allocated memory which needs to be freed. As we can see, the return type of the free() function is 'void' which means that the free function does not return any value and only frees up the allocated memory.
The number of bytes that are freed is equal to the number of bytes that were requested when the block was allocated (or reallocated, in the case of realloc). If memory_block is NULL(i.e. it does not point anywhere), then the pointer is ignored and free immediately returns.

If we try to free a pointer to a memory block that was not allocated by calloc, malloc, or realloc, it may affect subsequent allocation requests and cause errors in our program or might destroy the memory management making a system to crash.

The free() function does not change the value of the pointer, hence it still points to the same(now invalid) memory location.

Example of free() function using malloc and realloc:

#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int main()
{
	char *ptr;
	ptr = (char*) malloc(10*sizeof(char));
        
    strcpy(ptr,"Hello C++");
	cout << "Before reallocating: " << ptr << endl;

	ptr = (char*) realloc(ptr,20);
	strcpy(ptr,"Hello, Welcome to C++");
	cout << "After reallocating: " <<ptr << endl;

	free(ptr);
    cout << endl << "Garbage Value: " << ptr;

	return 0;
}

The output of the above code is:
Before reallocating: Hello C++
After reallocating: Hello, Welcome to C++
Garbage Value:

The delete or delete[] keyword

delete is a memory management operator in C++, which is used to deallocate memory that was previously dynamically allocated to a new object or a bunch of objects using the memory management operator-new. This is done to prevent memory leakage which may lead to crashing of the program.

Depending on the number of objects needed to be deallocated, we have two sytax of the delete operator:

1. Deallocation of a single object.

The syntax for deleting a single object is:

delete ptr-variable;

In the above syntax, the ptr-variable points to the memory address of an object whose allocated memory space has to be freed.
For example,

#include<iostream>
using namespace std;

int main()
{
int *d = new int(10);
cout<< "The value at the address pointed by the pointer variable : " << *d << "\n";
cout<< "The memory address allocated to the pointer variable : " << d << "\n";

delete d;

cout<< "The value at the address pointed by pointer variable : " << *d << "\n";
cout<< "The memory address allocated to the pointer variable : " << d;
}

The output of the above code is:
The value at the address pointed by the pointer variable : 10
The memory address allocated to the pointer variable : 0x68ae30
The value at the address pointed by pointer variable : 0
The memory address allocated to the pointer variable : 0x68ae30

2. Deallocation of multiple objects.

The syntax for deleting multiple objects is:

delete [] ptr-variable;

In the above syntax, the ptr-variable points to the memory address of the (array of) objects whose allocated memory space has to be freed.
For example,

#include<iostream>
using namespace std;

int main()
{
int *d = new int[100];
delete [] d;
}

The above code deallocates the 100 blocks of integer type memory(array) which was allocated with the help of new operator.

We can see that the delete operator does not destroy the pointer that is pointing to the object but it destroys the value or memory block pointed by the pointer.

We cannot use delete operator on a pointer to an object which has not been allocated with the new operator since it will give us unpredictable results. However, we can use delete on a pointer with the value 0. This means that, when new returns 0 on the failure of allocating the required memory, deleting the result of a failed new operation is harmless.
When the delete operator is called, it deallocates memory and calls the destructor for a single object created with new whereas when the delete [] operator is called, it deallocates memory and calls destructors for an array of objects created with new [].Using delete on a pointer returned by new [] or delete [] on a pointer returned by new results in undefined behavior.

The delete operator has a result type of void and therefore does not return a value.

Now that we have understood the basics of all the three keywords, let us compare them.

  1. free is a library function whereas delete and delete[] are both operator.
  2. free does not call any destructor while delete calls a destructor, if present whereas delete[] calls all the destructors that are present, according to the array size.
  3. free deallocates any block of memory created using malloc, calloc or realloc while delete deallocates a non-array object that has been created with new.whereas delete[] deallocates an array that has been created with new[].
  4. Freeing or deleting a null pointer with free, delete or delete[] causes no harm.
  5. free() uses C run time heap while delete and delete[] may be overloaded on class basis to use private heap.

We cannot allocate an object with malloc() and free it using delete or allocate with new and delete with free() or use realloc() on an array allocated by new.The C++ operators new and delete guarantee proper construction and destruction; where constructors or destructors need to be invoked, they are. The C-style functions malloc(), calloc(), free(), and realloc() donā€™t ensure that. Furthermore, there is no guarantee that the mechanism used by new and delete to acquire and release raw memory is compatible with malloc() and free().

With this article at OpenGenus, you must have complete idea of the differences of delete, delete[] and free in C++.