473,734 Members | 2,362 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Why does C++ need delete[] ?

I understand that "delete xp" deletes a scalar object and "delete [] xp"
deletes an array of objects, but what I don't understand is why you need
to tell the compiler which you're doing.

When you do "delete [] xp", the delete procedure (not sure if that's the
right terminology) obviously knows how many objects were allocated by
the corresponding "new" call. So, why can't it just know whether you
did "new x" or "new x[n]"?
Jul 22 '05 #1
15 2383
"Roy Smith" <ro*@panix.co m> wrote...
I understand that "delete xp" deletes a scalar object and "delete [] xp"
deletes an array of objects, but what I don't understand is why you need
to tell the compiler which you're doing.

When you do "delete [] xp", the delete procedure (not sure if that's the
right terminology) obviously knows how many objects were allocated by
the corresponding "new" call. So, why can't it just know whether you
did "new x" or "new x[n]"?


Existence of 'delete' along with 'delete[]' allows some deallocation
code to be optimised a bit better. For example, if you are sure that
there is only one object to be destroyed, there is no need to look up
the size of the "array", so 'delete' is a bit more efficient than its
"array" counterpart.

You could see the difference if you did a performance test on deleting
an array of size 1 versus a single object.

V
Jul 22 '05 #2

"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:XXTmd.1101 03$R05.47638@at tbi_s53...
"Roy Smith" <ro*@panix.co m> wrote...
I understand that "delete xp" deletes a scalar object and "delete [] xp"
deletes an array of objects, but what I don't understand is why you need
to tell the compiler which you're doing.

When you do "delete [] xp", the delete procedure (not sure if that's the
right terminology) obviously knows how many objects were allocated by
the corresponding "new" call. So, why can't it just know whether you
did "new x" or "new x[n]"?


Existence of 'delete' along with 'delete[]' allows some deallocation
code to be optimised a bit better. For example, if you are sure that
there is only one object to be destroyed, there is no need to look up
the size of the "array", so 'delete' is a bit more efficient than its
"array" counterpart.


I can't imagine much of an optimization advantage by using "delete []". How
much does one table lookup really cost for the array size? And if "delete
[]" was that much more efficient, why didn't they add a "free []" (along
with "malloc[]") feature as well?

I guess they chose to have "delete[]" to make it a compliment in syntax to
"new x[n]".
Jul 22 '05 #3
"delete []" will call destructor of each object element in array, while
delete will only call the destructor of first one.
Method Man wrote:
"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:XXTmd.1101 03$R05.47638@at tbi_s53...
"Roy Smith" <ro*@panix.co m> wrote...
I understand that "delete xp" deletes a scalar object and "delete [] xp"
deletes an array of objects, but what I don't understand is why you need
to tell the compiler which you're doing.

When you do "delete [] xp", the delete procedure (not sure if that's the
right terminology) obviously knows how many objects were allocated by
the corresponding "new" call. So, why can't it just know whether you
did "new x" or "new x[n]"?


Existence of 'delete' along with 'delete[]' allows some deallocation
code to be optimised a bit better. For example, if you are sure that
there is only one object to be destroyed, there is no need to look up
the size of the "array", so 'delete' is a bit more efficient than its
"array" counterpart.

I can't imagine much of an optimization advantage by using "delete []". How
much does one table lookup really cost for the array size? And if "delete
[]" was that much more efficient, why didn't they add a "free []" (along
with "malloc[]") feature as well?

I guess they chose to have "delete[]" to make it a compliment in syntax to
"new x[n]".

Jul 22 '05 #4
Method Man wrote:
"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:XXTmd.1101 03$R05.47638@at tbi_s53...
"Roy Smith" <ro*@panix.co m> wrote...
I understand that "delete xp" deletes a scalar object and "delete [] xp"
deletes an array of objects, but what I don't understand is why you need
to tell the compiler which you're doing.

When you do "delete [] xp", the delete procedure (not sure if that's the
right terminology) obviously knows how many objects were allocated by
the corresponding "new" call. So, why can't it just know whether you
did "new x" or "new x[n]"?


Existence of 'delete' along with 'delete[]' allows some deallocation
code to be optimised a bit better. For example, if you are sure that
there is only one object to be destroyed, there is no need to look up
the size of the "array", so 'delete' is a bit more efficient than its
"array" counterpart.

I can't imagine much of an optimization advantage by using "delete []". How
much does one table lookup really cost for the array size? And if "delete
[]" was that much more efficient, why didn't they add a "free []" (along
with "malloc[]") feature as well?

I guess they chose to have "delete[]" to make it a compliment in syntax to
"new x[n]".


new X[N] is the equivalent of
// warning - this code is not tested or checked and guarenteed broken
template <typename X>
X * MyNew( unsigned N )
{
// need to guarentee alignment - so statement below might be broken
void * t = malloc( sizeof( int ) + sizeof( X ) * N );

if ( ! t )
{
throw bad_alloc();
}

X * ptr = sizeof( int ) + (char *) t;

for ( int i = 0; i < N; ++ i )
{
// perform construction
new ( ptr + i ) X();
// oops need to handle exception --- broken again
}

* ( int * ) t = N;

return ptr;
}

delete[] is equivalent to

template <typename X>
void MyDelete( X * ptr )
{
if ( ! ptr ) return;

void * t = ( void * )( (char *) ptr ) - sizeof( int ) );
int N = * ( int * ) t;

for ( int i = N; i --; )
{
// call destructor
( ptr + i )->~X();

// oops need to handle exception --- baroke
}

free( t );

return ptr;
}

The point is, comparing delete[] and free() makes little sense.
Also, if you made new and new[] do the same thing, you would pay the
penalty of an extra 4 bytes for every object you new()ed. This can be a
very expensive thing to do when you have very large numbers of small
objects to create.


Jul 22 '05 #5
"Method Man" <a@b.c> wrote...

"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:XXTmd.1101 03$R05.47638@at tbi_s53...
"Roy Smith" <ro*@panix.co m> wrote...
>I understand that "delete xp" deletes a scalar object and "delete [] xp"
> deletes an array of objects, but what I don't understand is why you
> need
> to tell the compiler which you're doing.
>
> When you do "delete [] xp", the delete procedure (not sure if that's
> the
> right terminology) obviously knows how many objects were allocated by
> the corresponding "new" call. So, why can't it just know whether you
> did "new x" or "new x[n]"?


Existence of 'delete' along with 'delete[]' allows some deallocation
code to be optimised a bit better. For example, if you are sure that
there is only one object to be destroyed, there is no need to look up
the size of the "array", so 'delete' is a bit more efficient than its
"array" counterpart.


I can't imagine much of an optimization advantage by using "delete []".
How
much does one table lookup really cost for the array size? And if "delete
[]" was that much more efficient, why didn't they add a "free []" (along
with "malloc[]") feature as well?

I guess they chose to have "delete[]" to make it a compliment in syntax to
"new x[n]".


Actually, historically, you _had_ to tell 'delete[]' how many to destroy
just like you have to tell 'new[]' how many to create.

I bet you can find more in "Design and Evolution of C++".

Victor
Jul 22 '05 #6
Roy Smith wrote:
I understand that "delete xp" deletes a scalar object and "delete [] xp"
deletes an array of objects, but what I don't understand is why you need
to tell the compiler which you're doing.

When you do "delete [] xp", the delete procedure (not sure if that's the
right terminology) obviously knows how many objects were allocated by
the corresponding "new" call. So, why can't it just know whether you
did "new x" or "new x[n]"?


According to Bjarne Stroustrup,
"The C++ Programming Language: Third Edition",
Chapter 10 Classes, Section 4 Objects, Subsection 7 Arrays, page 250

"Like C, C++ doesn't distinguish between
a pointer to an individual object and
a pointer to the initial element of an array.
Consequently, the programmer must state whether
an array or an individual object is being deleted."

Jul 22 '05 #7
Method Man wrote:
I can't imagine much of an optimization advantage by using "delete []".
How much does one table lookup really cost for the array size?
This would compel the implementation to store an array size
for individual objects as well as for arrays of objects.
And if "delete []" was that much more efficient,
why didn't they add a "free []" (along with "malloc[]") feature as well?


malloc doesn't call any constructor and
free doesn't call any destructor.
Jul 22 '05 #8

"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > wrote in message
news:cn******** **@nntp1.jpl.na sa.gov...
Method Man wrote:
I can't imagine much of an optimization advantage by using "delete []".
How much does one table lookup really cost for the array size?


This would compel the implementation to store an array size
for individual objects as well as for arrays of objects.


Which is exactly what "free" needs to know since it doesn't care if the
pointer passed to it is a single (POD) object or an array of objects. So why
is this such an issue with "delete"?
And if "delete []" was that much more efficient,
why didn't they add a "free []" (along with "malloc[]") feature as well?


malloc doesn't call any constructor and
free doesn't call any destructor.


I understand that. The reason I drew the parallel of "delete" to "free" was
to point out that, regardless of whether one is dealing with POD types or
user types, "free" doesn't require any knowledge of deallocating an array or
a single object. "delete" _could_ have been implemented the same way. But,
they opted to have "delete[]" specifically for arrays.
Jul 22 '05 #9

"Gianni Mariani" <gi*******@mari ani.ws> wrote in message
news:O7******** ************@sp eakeasy.net...
Method Man wrote:
"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:XXTmd.1101 03$R05.47638@at tbi_s53...
"Roy Smith" <ro*@panix.co m> wrote...

I understand that "delete xp" deletes a scalar object and "delete [] xp"deletes an array of objects, but what I don't understand is why you needto tell the compiler which you're doing.

When you do "delete [] xp", the delete procedure (not sure if that's theright terminology) obviously knows how many objects were allocated by
the corresponding "new" call. So, why can't it just know whether you
did "new x" or "new x[n]"?

Existence of 'delete' along with 'delete[]' allows some deallocation
code to be optimised a bit better. For example, if you are sure that
there is only one object to be destroyed, there is no need to look up
the size of the "array", so 'delete' is a bit more efficient than its
"array" counterpart.
I can't imagine much of an optimization advantage by using "delete []". How much does one table lookup really cost for the array size? And if "delete []" was that much more efficient, why didn't they add a "free []" (along
with "malloc[]") feature as well?

I guess they chose to have "delete[]" to make it a compliment in syntax to "new x[n]".


new X[N] is the equivalent of
// warning - this code is not tested or checked and guarenteed broken
template <typename X>
X * MyNew( unsigned N )
{
// need to guarentee alignment - so statement below might be broken
void * t = malloc( sizeof( int ) + sizeof( X ) * N );

if ( ! t )
{
throw bad_alloc();
}

X * ptr = sizeof( int ) + (char *) t;

for ( int i = 0; i < N; ++ i )
{
// perform construction
new ( ptr + i ) X();
// oops need to handle exception --- broken again
}

* ( int * ) t = N;

return ptr;
}

delete[] is equivalent to

template <typename X>
void MyDelete( X * ptr )
{
if ( ! ptr ) return;

void * t = ( void * )( (char *) ptr ) - sizeof( int ) );
int N = * ( int * ) t;

for ( int i = N; i --; )
{
// call destructor
( ptr + i )->~X();

// oops need to handle exception --- baroke
}

free( t );

return ptr;
}

The point is, comparing delete[] and free() makes little sense.


Understood after reading some of your code.
Also, if you made new and new[] do the same thing, you would pay the
penalty of an extra 4 bytes for every object you new()ed. This can be a
very expensive thing to do when you have very large numbers of small
objects to create.


Well, that's how it's always been done with malloc/free in terms of storing
the allocated size for every memory block in a table. I still don't see why
those extra 4 bytes became an issue all of a sudden in C++.
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
2316
by: Fred Pacquier | last post by:
First off, sorry for this message-in-a-bottle-like post... I haven't been able to phrase my questions well enough to get a meaningful answer from Google in my research. OTOH, it is standard flattery (but true) that this group has a bunch of the nicest and most knowledgeable Usenet people around, and I know for a fact that there are some pretty good spam- related tools written in Python, so I thought I might get away with it :-) Yes,...
3
1327
by: webdev | last post by:
Hi, Code below dynamically adds an input box to a form, creating a new name attribute as it goes... (many thanks to Martin Honnen for getting me this far ;0) Problem is - in IE5.5 only the first form field (the hard-coded one) is recovered from the form, while with Mozilla/Firefox all fields are. The alert() just shows that the newly created element has no name in IE. Can anyone offer help with this bizarre problem (I thought any old...
5
1955
by: Noozer | last post by:
I have two Classes in use in an ASP application... The first Class is named "ORDER". It represents one job order. It has a Delete method, among others, which deletes it from my database. The second Class is named "ORDERS". It represents a collection of ORDER objects. Basically an array of ORDER objects. It has a Remove method that JUST removes the ORDER object from the collection - no data is erased.
6
2027
by: junw2000 | last post by:
Below is a simple code: #include <iostream> class base{ public: base(): i(11){std::cout<<"base constructor"<<'\n';} virtual void f() = 0; virtual ~base(){ std::cout<<"base destructor"<<'\n';} int i;
48
5835
by: avasilev | last post by:
Hi all, my question is: if i allocate some memory with malloc() and later free it (using free()), is there a possibility that a consequent malloc() will allocate memort at the same starting address and will return the same pointer as the previous malloc(). I would like to have confirmation on whether this is practically a concern when pointers are used to uniquely identify data structure instances - like in this example:
9
8171
by: rohits123 | last post by:
I have an overload delete operator as below ////////////////////////////////// void operator delete(void* mem,int head_type) { mmHead local_Head = CPRMemory::GetMemoryHead(head_type); mmFree(&local_Head,(char *)mem); CPRMemory::SetMemoryHeadAs(local_Head,head_type); } ///////////////////// void* operator new(size_t sz, int head_Type) {
19
4195
by: Angus | last post by:
I have a socket class CTestClientSocket which I am using to simulate load testing. I create multiple instances of the client like this: for (int i = 0; i < 5; i++) { CTestClientSocket* pTemp = new CTestClientSocket(this, ip, port); pTemp->Connect(); m_collClients.push_back(pTemp);
4
1701
by: Chris Fairles | last post by:
I recently implemented c++0x variants of tuple to take advantage of ECBO and then implemented unique_ptr using a tuple to hold the pointer - deleter pair so that sizeof(unique_ptr<int>) == sizeof(int*). It then came to my attention that its a lot of hoops to jump through just to take advantage of ECBO. I'm wondering whats preventing something like : struct SomeEmptyType {void f(){}};
5
3462
by: =?Utf-8?B?bXBhaW5l?= | last post by:
Hello, I am completely lost as to why I can't update a DropDownList inside a DetailsView after I perform an insert into an object datasource. I tried to simply it down to the core demostration: default.aspx:
0
8946
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9453
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9310
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9184
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6739
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6033
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4551
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3262
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2730
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.