What is the difference between delete
and delete[]
operators in C++?
-
You might find this question relevant http://stackoverflow.com/questions/1913343/how-could-pairing-new-with-delete-possibly-lead-to-memory-leak-only – sharptooth Mar 11 '10 at 14:45
-
7The issues with delete and delete[] are one reason why I like smart pointers, and using `vector<>` instead of an array whenever I can. – David Thornley Mar 11 '10 at 15:33
-
1http://stackoverflow.com/questions/1553382/pod-freeing-memory-is-delete-equal-to-delete – sbi Jan 12 '11 at 16:05
-
3@DavidThornley If you're using smart pointers you still need to know the difference in the sense that you still need to know not to write e.g. `std::unique_ptr
(new int[3])`, because it will call regular `delete` on the array which is undefined behaviour. Instead you need to use `std::unique_ptr – Arthur Tacca May 22 '20 at 22:34` -
1@DavidThornley You should probably use `std::array` when you know the size beforehand since it matches that use case better conceptually and will most likely be faster to boot. – user904963 Nov 30 '21 at 14:45
7 Answers
The delete
operator deallocates memory and calls the destructor for a single object created with new
.
The delete []
operator 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.

- 39,212
- 14
- 67
- 75
-
3I wonder if using delete on a new[] array of primitive types like int or char (no constructor/destructor) necessarily leads to undefined behavior, too. It seems the array size isn't stored anywhere when using primitive types. – thomiel Jul 06 '14 at 11:16
-
34If the standard doesn't define what happens when that is done, it is by definition "undefined behavior", even if your compiler deterministically does what you'd like it to do. Another compiler may do something entirely different. – Rob K Dec 23 '14 at 15:24
-
I made this error when I had an array of C strings like "char** strArray". If you have an array like I do, you need to iterate through the array and delete/free each element, then delete/free the strArray itself. Using "delete[]" on the array I have does not work since (as pointed out by the above comments and answer), IT CALLS DESTRUCTORS, it doesn't actually free each slot. – Katianie May 26 '16 at 03:22
The delete[]
operator is used to delete arrays. The delete
operator is used to delete non-array objects. It calls operator delete[]
and operator delete
function respectively to delete the memory that the array or non-array object occupied after (eventually) calling the destructors for the array's elements or the non-array object.
The following shows the relations:
typedef int array_type[1];
// create and destroy a int[1]
array_type *a = new array_type;
delete [] a;
// create and destroy an int
int *b = new int;
delete b;
// create and destroy an int[1]
int *c = new int[1];
delete[] c;
// create and destroy an int[1][2]
int (*d)[2] = new int[1][2];
delete [] d;
For the new
that creates an array (so, either the new type[]
or new
applied to an array type construct), the Standard looks for an operator new[]
in the array's element type class or in the global scope, and passes the amount of memory requested. It may request more than N * sizeof(ElementType)
if it wants (for instance to store the number of elements, so it later when deleting knows how many destructor calls to done). If the class declares an operator new[]
that additional to the amount of memory accepts another size_t
, that second parameter will receive the number of elements allocated - it may use this for any purpose it wants (debugging, etc...).
For the new
that creates a non-array object, it will look for an operator new
in the element's class or in the global scope. It passes the amount of memory requested (exactly sizeof(T)
always).
For the delete[]
, it looks into the arrays' element class type and calls their destructors. The operator delete[]
function used is the one in the element type's class, or if there is none then in the global scope.
For the delete
, if the pointer passed is a base class of the actual object's type, the base class must have a virtual destructor (otherwise, behavior is undefined). If it is not a base class, then the destructor of that class is called, and an operator delete
in that class or the global operator delete
is used. If a base class was passed, then the actual object type's destructor is called, and the operator delete
found in that class is used, or if there is none, a global operator delete
is called. If the operator delete
in the class has a second parameter of type size_t
, it will receive the number of elements to deallocate.

- 663
- 8
- 22

- 496,577
- 130
- 894
- 1,212
-
If if I have an array of pointers to objects, each of which may be nullptr, delete[] will not delete the objects pointed at by those pointers, right? delete[] will only delete the array elements which are physically embedded in the array. Like if you have an array of structs, then each struct destructor will get called. But not if you have an array of pointers to structs. The memory for the pointes will be freed, but not the memory for any structs that are pointed at by those pointers. – Shavais May 29 '21 at 16:08
This the basic usage of allocate/DE-allocate pattern in c++
malloc
/free
, new
/delete
, new[]
/delete[]
We need to use them correspondingly. But I would like to add this particular understanding for the difference between delete
and delete[]
1) delete
is used to de-allocate memory allocated for single object
2) delete[]
is used to de-allocate memory allocated for array of objects
class ABC{}
ABC *ptr = new ABC[100]
when we say new ABC[100]
, compiler can get the information about how many objects that needs to be allocated(here it is 100) and will call the constructor for each of the objects created
but correspondingly if we simply use delete ptr
for this case, compiler will not know how many objects that ptr
is pointing to and will end up calling of destructor and deleting memory for only 1 object(leaving the invocation of destructors and deallocation of remaining 99 objects). Hence there will be a memory leak.
so we need to use delete [] ptr
in this case.
-
5This should be the correct answer. None of the other answers mention the distinct difference: "but correspondingly if we simply use delete ptr for this case, compiler will not know how many objects that ptr is pointing to and will end up calling of destructor and deleting memory for only 1 object" – Don Larynx Jun 14 '15 at 01:22
-
1
-
@DogusUral Why? There are no destructors in C, so you just `free()` this and that. If you use a pseudo-destructor pattern, you have to call it once for every object using a `for` loop. – Kotauskas Oct 13 '19 at 15:22
-
@DonLarynx the *correct* difference is that mixing them up results in an ill-formed program. An implementation *might* know how many objects to destruct, or it *might not*. It is allowed to know that it was called wrong, and abort the program telling you where the problem is. – Caleth May 15 '20 at 08:34
When I asked this question, my real question was, "is there a difference between the two? Doesn't the runtime have to keep information about the array size, and so will it not be able to tell which one we mean?" This question does not appear in "related questions", so just to help out those like me, here is the answer to that: "why do we even need the delete[] operator?"

- 969
- 1
- 9
- 14
The operators delete
and delete []
are used respectively to destroy the objects created with new
and new[]
, returning to the allocated memory left available to the compiler's memory manager.
Objects created with new
must necessarily be destroyed with delete
, and that the arrays created with new[]
should be deleted with delete[]
.
C++ delete[] operator ensures that Destructor for all object allocated with new[] is called. The following example demonstrates the same. Also, delete[] must be preferred (if new[] used previously) when the class has a non-default destructor to release the acquired resources. Otherwise, it might result in memory leaks.
Common Code:-
#include <iostream>
using namespace std;
class memTest{
public:
static int num;
memTest(){
cout<<"Constructor from object " << num++ << endl;
}
~memTest(){
cout<<"Destructor from object " << --num << endl;
}
};
int memTest::num=0;
Example 1:- use of new[] and delete may result in undefined behavior.
int main() {
memTest* Test1=new memTest[3];
delete Test1; //<-----
return 0;
}
Output 1:-
Constructor from object 0
Constructor from object 1
Constructor from object 2
Destructor from object 2 //<-----
Example 2: The correct behavior is using new[] and delete[].
int main() {
memTest* Test1=new memTest[3];
delete[] Test1; //<-----
return 0;
}
Output 2:-
Constructor from object 0
Constructor from object 1
Constructor from object 2
Destructor from object 2
Destructor from object 1 //<-----
Destructor from object 0 //<-----

- 41
- 2
delete
is used for one single pointer and delete[]
is used for deleting an array through a pointer.
This might help you to understand better.

- 239,200
- 50
- 490
- 574

- 29
- 5