Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why *must* delete[] and delete be different?

I'm well aware that in C++, what delete[] is to new[], delete is to new. This is not about C++ syntax. I am wondering about the reasons delete[] was defined as something distinct from the plain delete. What are the implementation reasons for this?

Consider what happens with this code:

MyClass *object = new MyClass;
delete object;

When delete is encountered the memory manager has to lookup the object pointer value in its allocation structure, whatever it is, and mark the corresponding sizeof(MyClass) chunk of memory as free.

Now consider what happens with this code:

MyClass *array = new MyClass[ num_objects ];
delete [] array;

When delete is encountered the memory manager has to lookup the array pointer value in its allocation structure, whatever it is, find num_objects value from that structure , and mark the corresponding num_objects*sizeof(MyClass) chunk of memory as free.

Apart from num_objects being assumed 1 in the single object case and looked up in the internal data structure in the array case I don't see the difference. So why delete and delete[] couldn't have been spelled identically?

In other words, what's wrong with

MyClass *object = new MyClass;

being implemented as

MyClass *object = new MyClass[1];

so that C++ syntax wouldn't have to make distinction between delete and delete[] ?

like image 723
Michael Avatar asked Nov 21 '13 17:11

Michael


2 Answers

In principle, these could be implemented in the same way. However, there's a cost to storing the number of elements somewhere, iterating over those elements, and calling the destructor on each (both in terms of time and in terms of space.)

One of the core philosophies of C++ is "don't pay for what you don't use." Since there is an extra cost associated with the array-based allocation and deallocation routines that programmers might not want to pay for, the language explicitly makes the two operations separate.

Hope this helps!

like image 118
templatetypedef Avatar answered Nov 10 '22 02:11

templatetypedef


Firstly, the functionality of new/delete is different from that of new[]/delete[]. The former can be used to perform polymorphic allocation and polymorphic deletion. The latter does not support polymorphism at all. Arrays in C++ are not polymorphic, only individual objects are. It is probably possible to forcefully converge these two functionalities into one, in order to allow polymorphic deletion of single objects and still keep polymorphic deletion of arrays illegal, but it won't look pretty.

Secondly, as you probably know, a typical implementation of new[] will store the exact number of objects in the allocated array to be used later by delete[] to call the proper number of destructors. However, most modern implementations actually go through the trouble of not storing the array size when the allocated type has trivial destructor.

Why do they do that? They do that to save memory, i.e. to avoid storing the size when it can be avoided. Note that they go through all that trouble even in situations where the relative memory loss is generally small (one size_t field compared to an array of objects).

So, apparently this kind of memory saving technique is considered to be worth the effort.

Under such circumstances it is obvious that it should be even more worth it in situations when the array size is known to be exactly 1, i.e. from this point of view implementing new T through new T[1] would be exceedingly wasteful.

like image 26
AnT Avatar answered Nov 10 '22 02:11

AnT