Connecting Tech Pros Worldwide Forums | Help | Site Map

delete[] of POD

MaxMax
Guest
 
Posts: n/a
#1: Oct 25 '05
int *p;
p = new int[10];

void *q = (void*)p;
delete[] q;

Is this valid if p is guaranteed to be a POD? (don't ask why... there is a
reason I need this. Clearly I will create p in function, use p in another
function that know what type p is and delete p in a function that for
simplicity won't know what p is)

Reading the MSDN it seems that

"The global operator delete function, if declared, takes a single argument
of type void *, which contains a pointer to the object to deallocate. The
return type is void (operator delete cannot return a value). Two forms exist
for class-member operator delete functions:"

so it should be ok But this is the MSDN guide :-)

--- bye



Ferdi Smit
Guest
 
Posts: n/a
#2: Oct 25 '05

re: delete[] of POD


MaxMax wrote:[color=blue]
> int *p;
> p = new int[10];
>
> void *q = (void*)p;
> delete[] q;
>
> Is this valid if p is guaranteed to be a POD? (don't ask why... there is a
> reason I need this. Clearly I will create p in function, use p in another
> function that know what type p is and delete p in a function that for
> simplicity won't know what p is)
>
> Reading the MSDN it seems that
>
> "The global operator delete function, if declared, takes a single argument
> of type void *, which contains a pointer to the object to deallocate. The
> return type is void (operator delete cannot return a value). Two forms exist
> for class-member operator delete functions:"
>
> so it should be ok But this is the MSDN guide :-)
>
> --- bye
>
>[/color]

operator delete[] has a void* as parameter in the standard, so you're fine.

--
Regards,

Ferdi Smit (M.Sc.)
Email: Ferdi.Smit@cwi.nl
Room: C0.07 Phone: 4229
INS3 Visualization and 3D Interfaces
CWI Amsterdam, The Netherlands
Alf P. Steinbach
Guest
 
Posts: n/a
#3: Oct 25 '05

re: delete[] of POD


* Ferdi Smit:[color=blue]
> MaxMax wrote:[color=green]
> > int *p;
> > p = new int[10];
> >
> > void *q = (void*)p;
> > delete[] q;
> >
> > Is this valid if p is guaranteed to be a POD? (don't ask why... there is a
> > reason I need this. Clearly I will create p in function, use p in another
> > function that know what type p is and delete p in a function that for
> > simplicity won't know what p is)
> >
> > Reading the MSDN it seems that
> >
> > "The global operator delete function, if declared, takes a single argument
> > of type void *, which contains a pointer to the object to deallocate. The
> > return type is void (operator delete cannot return a value). Two forms exist
> > for class-member operator delete functions:"
> >
> > so it should be ok But this is the MSDN guide :-)
> >[/color]
>
> operator delete[] has a void* as parameter in the standard, so you're fine.[/color]

Sorry, that's an incorrect inference.

The standard defines this as Undefined Behavior, and in case somebody should
not see that implication, it states that explicitly for void* in note 73:

[context: delete array] "... an object cannot be deleted using a pointer of
type void* because ...".

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Ferdi Smit
Guest
 
Posts: n/a
#4: Oct 25 '05

re: delete[] of POD


Alf P. Steinbach wrote:[color=blue][color=green]
>>
>>operator delete[] has a void* as parameter in the standard, so you're fine.[/color]
>
>
> Sorry, that's an incorrect inference.
>
> The standard defines this as Undefined Behavior, and in case somebody should
> not see that implication, it states that explicitly for void* in note 73:
>
> [context: delete array] "... an object cannot be deleted using a pointer of
> type void* because ...".
>[/color]

I think that refers to an array of void which is impossible (size 0, a
similar reason to why an (empty) instantiated object has size at least
1); and thus you can't delete[] a true void*. But in max's case the
underlying data is in fact of another type (int*). The operator delete[]
takes a void*, so whatever pointer you pass it, it will be cast to a
void* first before the operator runs anyway.

--
Regards,

Ferdi Smit (M.Sc.)
Email: Ferdi.Smit@cwi.nl
Room: C0.07 Phone: 4229
INS3 Visualization and 3D Interfaces
CWI Amsterdam, The Netherlands
Alf P. Steinbach
Guest
 
Posts: n/a
#5: Oct 25 '05

re: delete[] of POD


* Ferdi Smit:[color=blue]
> Alf P. Steinbach wrote:[color=green][color=darkred]
> >>
> >>operator delete[] has a void* as parameter in the standard, so you're fine.[/color]
> >
> >
> > Sorry, that's an incorrect inference.
> >
> > The standard defines this as Undefined Behavior, and in case somebody should
> > not see that implication, it states that explicitly for void* in note 73:
> >
> > [context: delete array] "... an object cannot be deleted using a pointer of
> > type void* because ...".
> >[/color]
>
> I think that refers to an array of void which is impossible (size 0, a
> similar reason to why an (empty) instantiated object has size at least
> 1); and thus you can't delete[] a true void*.[/color]

There is no such thing as a "true void*" ;-) Except the nullpointer of void*
type, in which case you have no object to be deleted.

[color=blue]
> But in max's case the
> underlying data is in fact of another type (int*). The operator delete[]
> takes a void*, so whatever pointer you pass it, it will be cast to a
> void* first before the operator runs anyway.[/color]

That doesn't matter. The compiler can't infer the size or type of the array
elements statically. The standard couldn't be more clear on this issue: it's
Undefined Behavior.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
John Carson
Guest
 
Posts: n/a
#6: Oct 25 '05

re: delete[] of POD


"Ferdi Smit" <Ferdi.Smit@cwi.nl> wrote in message news:IowutL.1zx@cwi.nl[color=blue]
>
> I think that refers to an array of void which is impossible (size 0, a
> similar reason to why an (empty) instantiated object has size at least
> 1); and thus you can't delete[] a true void*. But in max's case the
> underlying data is in fact of another type (int*). The operator
> delete[] takes a void*, so whatever pointer you pass it, it will be
> cast to a void* first before the operator runs anyway.[/color]

You need to distinguish between delete[] and operator delete[], which are
easily confused.

delete[] does two things:

1. it calls the destructor for the objects in the array, and then
2. it calls operator delete[] to deallocate memory.

Once the destructor has run, the object no longer exists and hence it is not
surprising that operator delete[] is given a void* pointer. To see the
effect of using delete[] with a void* pointer, run the following:

#include <iostream>

class Test
{
public:
~Test()
{
std::cout << "Destructor called\n";
}
};

int main()
{
Test *ptest = new Test[4];
void * ptr = (void*)ptest;
delete [] ptr;
return 0;
}

The result of this is undefined, but I predict with reasonable confidence
that the destructor will not be called. If, by contrast, you call delete[]
on ptest, then the destructor will be called.

Of course, if your array members don't have destructors, then you may get
away with calling delete[] on a void* pointer. There is no guarantee,
however. The behaviour is undefined.

--
John Carson

Ferdi Smit
Guest
 
Posts: n/a
#7: Oct 25 '05

re: delete[] of POD


John Carson wrote:[color=blue]
> You need to distinguish between delete[] and operator delete[], which are
> easily confused.
>
> delete[] does two things:
>
> 1. it calls the destructor for the objects in the array, and then
> 2. it calls operator delete[] to deallocate memory.
>
> Once the destructor has run, the object no longer exists and hence it is
> not
> surprising that operator delete[] is given a void* pointer. To see the
> effect of using delete[] with a void* pointer, run the following:
>
> #include <iostream>
>
> class Test
> {
> public:
> ~Test()
> {
> std::cout << "Destructor called\n";
> }
> };
>
> int main()
> {
> Test *ptest = new Test[4];
> void * ptr = (void*)ptest;
> delete [] ptr;
> return 0;
> }
>
> The result of this is undefined, but I predict with reasonable confidence
> that the destructor will not be called. If, by contrast, you call delete[]
> on ptest, then the destructor will be called.
>
> Of course, if your array members don't have destructors, then you may get
> away with calling delete[] on a void* pointer. There is no guarantee,
> however. The behaviour is undefined.
>[/color]

Ah, alright. Then this time I stand corrected :) (arrays are evil anyway :P)

--
Regards,

Ferdi Smit (M.Sc.)
Email: Ferdi.Smit@cwi.nl
Room: C0.07 Phone: 4229
INS3 Visualization and 3D Interfaces
CWI Amsterdam, The Netherlands
MaxMax
Guest
 
Posts: n/a
#8: Oct 29 '05

re: delete[] of POD


>> Of course, if your array members don't have destructors, then you may get[color=blue][color=green]
>> away with calling delete[] on a void* pointer. There is no guarantee,
>> however. The behaviour is undefined.[/color][/color]
So, if I know I'm working with a POD, can I directly use the operator
delete? POD don't have destructors.

--- bye


Ivan Vecerina
Guest
 
Posts: n/a
#9: Oct 29 '05

re: delete[] of POD


"MaxMax" <none@none.com> wrote in message
news:n2K8f.37014$Pe2.675133@twister2.libero.it...
: >> Of course, if your array members don't have destructors, then you
may get
: >> away with calling delete[] on a void* pointer. There is no
guarantee,
: >> however. The behaviour is undefined.
: So, if I know I'm working with a POD, can I directly use the
operator
: delete? POD don't have destructors.

Not if you want your code to be portable and standards-compliant.

Let me restate what was written above about this being undefined
behavior:
you can do it for a POD, and it is even likely to work as you expect
on
your platform/compiler. However, code that uses this trick will not
be portable, and will behave unexpectedly on some other platform,
or when you port your code to a new version of your compiler.

In other words: don't do it.
Allocated memory always must be disposed in a way that strictly
matches the allocation method.

--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact
form
Brainbench MVP for C++ <> http://www.brainbench.com


Jim Langston
Guest
 
Posts: n/a
#10: Oct 31 '05

re: delete[] of POD


"Ivan Vecerina" <INVALID_use_webform@ivan.vecerina.com> wrote in message
news:djvvef$fgq$1@news.hispeed.ch...[color=blue]
> "MaxMax" <none@none.com> wrote in message
> news:n2K8f.37014$Pe2.675133@twister2.libero.it...
> : >> Of course, if your array members don't have destructors, then you
> may get
> : >> away with calling delete[] on a void* pointer. There is no
> guarantee,
> : >> however. The behaviour is undefined.
> : So, if I know I'm working with a POD, can I directly use the
> operator
> : delete? POD don't have destructors.
>
> Not if you want your code to be portable and standards-compliant.
>
> Let me restate what was written above about this being undefined
> behavior:
> you can do it for a POD, and it is even likely to work as you expect
> on
> your platform/compiler. However, code that uses this trick will not
> be portable, and will behave unexpectedly on some other platform,
> or when you port your code to a new version of your compiler.
>
> In other words: don't do it.
> Allocated memory always must be disposed in a way that strictly
> matches the allocation method.[/color]

Seeing how this is POD, couldn't you just call
delete q;
as the destructors don't need to be called?

OP question:
int *p;
p = new int[10];

void *q = (void*)p;
delete[] q;

Is this valid if p is guaranteed to be a POD? ...


Ron Natalie
Guest
 
Posts: n/a
#11: Nov 1 '05

re: delete[] of POD


Jim Langston wrote:
[color=blue]
> Seeing how this is POD, couldn't you just call
> delete q;
> as the destructors don't need to be called?[/color]

The standard makes no such exception for POD types.
[color=blue]
>
> OP question:
> int *p;
> p = new int[10];
>
> void *q = (void*)p;
> delete[] q;
>
> Is this valid if p is guaranteed to be a POD? ...
>
>[/color]

It's never valid. You must pass delete[] the exact same
type and value you got from new [].

The only time you can pass something to delete that's a
different type than what was new is for the single object
case where you have a base class pointer with a derived
destructor. Even then you can't use void*. It has to
be a base class, not any pointer you converted.
Closed Thread