how does the delete operator work? Is it better then free()?. Also if u do ptr=new char[10]
, then delete using delete ptr
, how does the pointer know how many locations to delete.
views:
377answers:
7There is only delete
operator, free
exist only as function. Under C++, you are encouraged to use new
/delete
over malloc()
/free()
.
There is an internal "magic" in delete operator. When an array is created with new[]
, the size of array is stored in the metadata at the memory block. delete[]
makes use of that information.
All this is of course compiler-, OS-, optimizer- and implementation-dependent.
Adding to @Vlad's answer if you allocate memory using new[] form of the operator like:
char *c = new char[10];
then you have to use the corresponding delete form:
delete[] c;
You have to explicitly tell the compiler to use the metadata during deallocation.
[EDIT]
Why you cannot use char c[]
Because the compiler needs to know the size it needs to set aside for variable c at compile time. However, using the new[] form tells it to defer allocation until runtime. Hence, the compiler error.
In C++, a constructor is called using new, but not when using malloc. Similarly a destructor is called when using delete, but not when using free.
If you have new-ed an array using MyClass* x = new MyClass[25], then you need to call delete[] x, so that they system knows that it's deleting (and destructing) a group of objects instead of a single one.
The implementation works out the number of elements to destroy (when using delete[]) for you. For example:
- new char[10] could allocates a few extra bytes, put the number of elements at the beginning, then return the pointer to the first element after that. delete[] could then look behind the pointer at the stored count
- store the equivalent of std::map<void*, size_t>, and new T[n] would create a key with the returned pointer, and a value with the count. delete[] would look up the pointer in this map
- something completely different. It doesn't matter to you how it's done, just that it is done (and as other answers have pointed out, use delete[] with new[]!!)
if you do a non-array type:
T t = new T;
// ...
delete t;
It will know how much to delete because it knows how big a T is. If you do an array:
T t* = new T[10];
// ...
delete [] t;
It will lay down some extra info with the allocation to tell it how much to delete. Note, we use delete [] t
with the extra []
in there to tell it it's an array. If you don't do that it will think it's just a T
and only free that much memory.
Always use delete
if you use new
and free
if you use malloc
. new
does 2 things first it allocates the memory, then it constructs the object. Similarly delete
calls the destructor and then frees the memory. malloc\free
only deal with the memory allocation and deallocation.
It is not a question of better or worse. Both are operations with the same goal, allocating and releasing memory, but usually used within a different context of C vs. C++. Furthermore, there are some important differences between the two sets of operations:
new
/delete
are C++ keywords, and are not available in the C languagenew
/delete
are type safe, whereasmalloc()
/free()
are not. This means that pointers returned bymalloc()
andfree()
arevoid
pointers that need to be cast to the correct type.new
/delete
implicitly support array allocation and deletion using thenew[]
anddelete[]
syntax using meta-data supplied by the compiler,malloc()
/free()
do not support this syntax- applying
new
/delete
to a class typeT
will call the constructor and destructor respectively ofT
,malloc()
/free()
do not call the constructor and destructor ofT
malloc()
will returnNULL
in case of memory exhaustion,new
will throw an exception
Note that to prevent memory corruption, memory allocated using new
should be freed using delete
. The same holds for memory allocated using malloc()
, which should be freed using free()
.
Specifically answering your question, the delete operator invokes the destructor, where free does not; hence the reason you don't want to mix malloc/free with new/delete.
When the compiler's library grabs memory from the heap, it grabs a little more than you ask for which includes space for it's house keeping, some meta data, and if required, padding.
Say you malloc 128 bytes, or new an array of eight 16 byte-sized objects. The compiler might actually grab 256 bytes, include a small heap management block at the start, record that it gave you 128 but grabbed 256, and return you an offset into that 256 block somewhere after it's header. You are guaranteed that from that pointer you have 128 bytes that you may use, but if you go beyond that, you could run into trouble.
The free and delete operators under the hood will take the pointer you were handed, back up a known offset, read it's header block, and know to release 256 bytes back to the heap.