Discussion:
Call of a destructor for NULL pointer
(too old to reply)
Vladimir Grigoriev
2009-09-21 15:04:01 UTC
Permalink
Should be destructor called always irrespective of that a pointer is equal
to 0?
What does the C++ standard say about this?

Example

T *p = 0;

delete p; // will be a destructor of T object called here?

It seems that operation 'delete p' when p == 0 is not safe. I asked this
question because inside of some code of std::auto_ptr I see the following

~auto_ptr()
{
delete p;
}

Vladimir Grigoriev
Vladimir Grigoriev
David Webber
2009-09-21 15:19:44 UTC
Permalink
Post by Vladimir Grigoriev
Should be destructor called always irrespective of that a pointer is equal
to 0?
No - how can it be? A NULL pointer means that nothing is being pointed
to, so there is nothing to destroy.
Post by Vladimir Grigoriev
What does the C++ standard say about this?
Example
T *p = 0;
delete p; // will be a destructor of T object called here?
This is safe - it does nothing. That is so you can do

delete p;

when p may be pointing to a valid object or it may be NULL.

You can of course (if you wish) do

if( p ) delete p;

but the effect is the same.
Post by Vladimir Grigoriev
It seems that operation 'delete p' when p == 0 is not safe.
It may *seem* so, but in fact it is explicitly defined to be safe, I think
in the standard, but certainly in the most recent versions of VC++.

Dave
--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
Vladimir Grigoriev
2009-09-21 16:01:29 UTC
Permalink
I will look my test code one more tomorrow.

there was such code (as I remember)

std::auto_ptr<Widget> pw1( new Widget );
std::auto_ptr<Widget> pw2;

std::auto_ptr<Widget> func( std::auto_ptr<Widget> wp );

and in the debug mode for the statement below I saw that a destructor of
Widget is called two times

pw2 = func( pw1 );

for (as I thought) temporary objects.

I will check the code anew.

Vladimir Grigoriev
Post by David Webber
Post by Vladimir Grigoriev
Should be destructor called always irrespective of that a pointer is
equal to 0?
No - how can it be? A NULL pointer means that nothing is being pointed
to, so there is nothing to destroy.
Post by Vladimir Grigoriev
What does the C++ standard say about this?
Example
T *p = 0;
delete p; // will be a destructor of T object called here?
This is safe - it does nothing. That is so you can do
delete p;
when p may be pointing to a valid object or it may be NULL.
You can of course (if you wish) do
if( p ) delete p;
but the effect is the same.
Post by Vladimir Grigoriev
It seems that operation 'delete p' when p == 0 is not safe.
It may *seem* so, but in fact it is explicitly defined to be safe, I think
in the standard, but certainly in the most recent versions of VC++.
Dave
--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
Scot T Brennecke
2009-09-22 07:34:30 UTC
Permalink
Sure, you'll get a destructor called for temporary auto_ptr abjects because you passed the wp parameter by value, so a copy is made.
But this doesn't have anything to do with calling a destructor for a NULL pointer.
delete p does not call a destructor if p is NULL.
Post by Vladimir Grigoriev
I will look my test code one more tomorrow.
there was such code (as I remember)
std::auto_ptr<Widget> pw1( new Widget );
std::auto_ptr<Widget> pw2;
std::auto_ptr<Widget> func( std::auto_ptr<Widget> wp );
and in the debug mode for the statement below I saw that a destructor of
Widget is called two times
pw2 = func( pw1 );
for (as I thought) temporary objects.
I will check the code anew.
Vladimir Grigoriev
Post by David Webber
Post by Vladimir Grigoriev
Should be destructor called always irrespective of that a pointer is
equal to 0?
No - how can it be? A NULL pointer means that nothing is being pointed
to, so there is nothing to destroy.
Post by Vladimir Grigoriev
What does the C++ standard say about this?
Example
T *p = 0;
delete p; // will be a destructor of T object called here?
This is safe - it does nothing. That is so you can do
delete p;
when p may be pointing to a valid object or it may be NULL.
You can of course (if you wish) do
if( p ) delete p;
but the effect is the same.
Post by Vladimir Grigoriev
It seems that operation 'delete p' when p == 0 is not safe.
It may *seem* so, but in fact it is explicitly defined to be safe, I think
in the standard, but certainly in the most recent versions of VC++.
Dave
--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
Vladimir Grigoriev
2009-09-22 09:51:14 UTC
Permalink
I have understood the problem. The previous night I played with Borland C++
5.0. Today I looked through generated assembler code and saw the following

delete p; // std::auto_ptr<Widget> p;

push 0x03
mov edx,[ebp+0x08]
push dword ptr[edx]
call Widget::~Widget()

~Widget()
push ebp
mov ebp,esp
cmp dword ptr[ebp+0x08],0x00
jz +0x22
...
pop ebp
ret

i.e. the Borland C++ 5.0 compiler inserts checking of the 'this' inside a
destructor. So in debug mode I saw that Widget destructor was called.

After that I thought about to change the auto_ptr destructor the following
way :)

~auto_ptr()
{
if ( the_p ) delete the_p;
}

Vladimir Grigoriev
Post by Scot T Brennecke
Sure, you'll get a destructor called for temporary auto_ptr abjects
because you passed the wp parameter by value, so a copy is made. But this
doesn't have anything to do with calling a destructor for a NULL pointer.
delete p does not call a destructor if p is NULL.
Mateusz Loskot
2009-09-26 16:59:25 UTC
Permalink
Post by Vladimir Grigoriev
After that I thought about to change the auto_ptr destructor the
following way :)
~auto_ptr() { if ( the_p ) delete the_p; }
Assuming you use correct implementation of C++, such pseudo-fix is a
waste of energy.

Best regards,
--
Mateusz Loskot, http://mateusz.loskot.net
Charter Member of OSGeo, http://osgeo.org
Giovanni Dicanio
2009-09-21 15:30:45 UTC
Permalink
Post by Vladimir Grigoriev
Should be destructor called always irrespective of that a pointer is equal
to 0?
What does the C++ standard say about this?
Example
T *p = 0;
delete p; // will be a destructor of T object called here?
It seems that operation 'delete p' when p == 0 is not safe.
'delete p' is just fine.

C++ FAQ Lite is explicit about that:

[16.8] Do I need to check for NULL before delete p?
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.8

Giovanni
Mateusz Loskot
2009-09-26 16:56:35 UTC
Permalink
Post by Vladimir Grigoriev
Should be destructor called always irrespective of that a pointer is equal
to 0?
What does the C++ standard say about this?
Example
T *p = 0;
delete p; // will be a destructor of T object called here?
It seems that operation 'delete p' when p == 0 is not safe.
It is perfectly safe to do

int* p = 0;
delete p;

The standard guarantees that in 3.7.3.2/3:

The value of the first argument supplied to one of the deallocation
functions provided in the standard library may be a null pointer value;
if so, the call to the deallocation function has no effect.

Best regards,
--
Mateusz Loskot, http://mateusz.loskot.net
Charter Member of OSGeo, http://osgeo.org
Loading...