0

In C, free() is used to release the memory, say free(ptr). As I understand, extra memory is allocated before ptr in the library code to store the block size information. After free() is called, the whole block is tracked and then released.

In C++, there are two forms of new and delete. One is for array. If new[] is used, delete[] should be used. For example,

int ptr = new [10]; 
delete [] ptr;

Question 1: can I use delete ptr here? If that is OK, what if delete ptr + 2?

Question 2: If delete[] has to be used to match new[], why do we need two forms of delete? Just one form, say delete, would be enough.

Thanks for all the suggestions!

Thank Mgetz. Question 2 should be: why c++ standard proposed both delete [] and delete if there is only one correct form at any situation?

SuperBald
  • 109
  • 1
  • 12

2 Answers2

2

Q1: You can use delete, but it is wrong.

This will usually "work" insofar as it will correctly free the allocated memory, but it will not call destructors properly. For trivial types, you will often not see any difference, but that doesn't mean it isn't wrong anyway. In any case it is undefined behavior which you should avoid if you can (invoking UB forfeits any guarantees that your code will work, it might of course still work, but you can never be 100% sure).
Deleting ptr+2 is also undefined behavior and will almost certainly not "work", not even a little. Usually, this will simply result in a program crash.

Q2: You need the two because they mean different things. One means "delete this pointer-to-single-object" whereas the other means "delete this pointer-to-array-of-objects".
Obviously, the compiler needs to generate different code for those different things.

Damon
  • 67,688
  • 20
  • 135
  • 185
  • For point 1, glibc tells you at runtime if you have a mismatched allocate/deallocate pair and depending on the value of MALLOC_CHECK_ in the environment, it may abort the program. That's a noticeable difference. – SirGuy Feb 15 '14 at 00:59
  • @GuyGreer: My version doesn't seem to (it really seems to "work" normally, except of course for not calling destructors properly), but if your build warns or even aborts that is great. I very much prefer aborts or hard crashes instead of "works anyway" behavior that hides errors. Aborting hard and early enforces writing proper code. – Damon Feb 15 '14 at 11:33
0

You need the two forms because, unlike malloc and free, new and delete do more than just allocate and deallocate memory; they also construct and destruct the object(s) respectively.

new and delete deal with scalar objects, while new[] and delete[] deal with arrays of objects.

When you call new T[n], it'll allocate enough memory for n copies of T, and then construct n instances within the allocated memory. Similarly, calling delete[] will cause destruction of those n instances followed by deallocation.

Obviously, since you do not pass n to delete[] that information is being stashed away somewhere by the implementation, but the standard doesn't require an implementation to destroy all n objects if you call delete instead. The implementation could just destroy the first object, it might behave correctly and destroy all n objects or it might cause demons to fly out of your nose.

Simply put, it's undefined behavior, there's no telling what'll happen, it's best imperative you avoid it.

Praetorian
  • 106,671
  • 19
  • 240
  • 328