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[]
?
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With