views:

377

answers:

7

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.

+13  A: 

There 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.

Vlad
I suggest changing `new` to `new[]` and `delete` to `delete[]`.
FredOverflow
If you mistakenly use `delete ptr` instead of `delete [] ptr`, the "magic" may or may not work properly, again very implementation dependent.
Mark Ransom
@FredOverflow, @Mark: indeed, thanks!
Vlad
I will never understand why C++ passes array-sizes around internal, but doesn't give you access to them, forcing you to pass around array-sizes on your own.
BlueRaja - Danny Pflughoeft
@BlueRaja: if you create an array that is n bytes long, C++ is not obligated to allocate exactly n bytes for that array -- it can allocate more, for instance to ensure alignment.
Michael Williamson
@BlueRaja: because C++ is not _required_ to know the array size. The concrete implementation may know what is the size of the array in _bytes_, but don't know the maximal array _index_ (because it doesn't care about item's size). On the other hand, if you need to know the size as well, perhaps you need `std::vector` instead of array?
Vlad
+1  A: 

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.

ardsrk
`char c[] = new char[10];` does not compile, you should change `c[]` to `*c`.
FredOverflow
that statement is not legal, you cannot change the pointer of a character array. I think you meant to say char *c
Thanks for pointing out the error. Made the correction.
ardsrk
even if you do **delete c**, I bet it will work. don't ask me why :)>
Gollum
+2  A: 
  1. 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.

  2. 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.

Joel
+2  A: 

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[]!!)
AshleysBrain
+4  A: 

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.

Matt Price
+2  A: 

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 language
  • new / delete are type safe, whereas malloc() / free() are not. This means that pointers returned by malloc() and free() are void pointers that need to be cast to the correct type.
  • new / delete implicitly support array allocation and deletion using the new[] and delete[] syntax using meta-data supplied by the compiler, malloc() / free() do not support this syntax
  • applying new / delete to a class type T will call the constructor and destructor respectively of T, malloc() / free() do not call the constructor and destructor of T
  • malloc() will return NULL 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().

Ton van den Heuvel
+2  A: 

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.

Walt Stoneburner