C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

strange behaviour of STL destructor
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Mookie
Guest





PostPosted: Wed Sep 24, 2003 10:34 pm    Post subject: strange behaviour of STL destructor Reply with quote



Hi group,

I'm in need of some help. I don't understand why my application is
crashing. I boiled down my source code and now I'm at least able to
point my finger at the list destructor ~list(). The following sample
code mirrors more or less my code and this is also crashing. The
if-condition in my destructor is there on purpose, because in my
application there is a library call to free things up and I musn't
call this if the pointer is NULL.
I'm thankfull if someone could explain to me why the code is crashing,
and why the destructor is called so often (myList should be empty,
should't it?)

#include <list>

class Test
{
public:
Test(int a){pt = new int(a);}
Test(const Test& rhs)
{
int tmp = *(rhs.pt);
pt = new int(tmp);
}
~Test()
{
cout << "Destructor was called" << endl;
if (pt !=0)
delete pt;
pt = 0;
}
private:
int* pt;
};

int main()
{
list Test a(5);
myList.push_back(a);
/* If I comment out the following line there will be no crash! */
myList.~list();
return 0;
}


I'm compiling on HP-UX 10.2, with g++ (gcc version 2.95.2 19991024
(release))

Cheers,
Bernd

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Erik Max Francis
Guest





PostPosted: Thu Sep 25, 2003 1:17 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote



Mookie wrote:

Quote:
I'm in need of some help. I don't understand why my application is
crashing. I boiled down my source code and now I'm at least able to
point my finger at the list destructor ~list().

The circumstances under which you want to call a destructor explicitly
are extremely rare, and this is a good example why. The list is deleted
automatically (since it's an auto variable), and so C++ itself will call
the destructor for you. Since you're calling it unnecessarily, that
means that it's getting called twice and that results in undefined
behavior.

Just remove the explicit call to the destructor and it will work fine.
Even for objects allocated dynamically with new you shouldn't be calling
the _destructor_ explicitly, you should instead be deleting it with
delete.

--
Erik Max Francis && [email]max (AT) alcyone (DOT) com[/email] && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ I love mankind; it's people I can't stand.
__/ Charles Schultz

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Siemel Naran
Guest





PostPosted: Thu Sep 25, 2003 1:29 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote



"Mookie" <bernd_moeller (AT) hotmail (DOT) com> wrote in message

Quote:
class Test
{
public:
Test(int a){pt = new int(a);}
Test(const Test& rhs)
~Test()

Don't forget to write operator= too Smile.


Quote:
int main()
{
list<Test> myList;
Test a(5);
myList.push_back(a);
/* If I comment out the following line there will be no crash! */
myList.~list();
return 0;
}

Your program calls the destructor of myList twice. First time is your
explicit call. Second time is at the closing } where the system
automatically destroys local objects. Probably the implementation of your
destructor that does set m_pRoot to NULL in the destructor, but it's not
required too because you're not supposed to use the object again afterwards.

There is no reason to call the destructor explicitly. If you really must
use placement new to construct a new list right after destroying it.

But if you want to erase all elements in the list consider these two options

myList.clear();
list<Test>().swap(myList);

--
+++++++++++
Siemel Naran


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Heinz Ozwirk
Guest





PostPosted: Thu Sep 25, 2003 1:39 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote

"Mookie" <bernd_moeller (AT) hotmail (DOT) com> schrieb im Newsbeitrag news:47b8e6cd.0309240604.329bd680 (AT) posting (DOT) google.com...
: int main()
: {
: list<Test> myList;
: Test a(5);
: myList.push_back(a);
: /* If I comment out the following line there will be no crash! */
: myList.~list();
: return 0;
: }

Don't call destructors explicitly. The compiler will take care of that.

In your code, the destructor of myList will be called twice. First you call it explicitly, and at the end of main the compiler creates a second
call. And I'm almost certain that it is in the second call your program crashs. So just remove the explicit call and let the compiler do its
work.

Heinz

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Dhruv
Guest





PostPosted: Thu Sep 25, 2003 1:44 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote

On Wed, 24 Sep 2003 18:34:22 -0400, Mookie wrote:
[snipped some code].......

Quote:
int main()
{
list<Test> myList;
Test a(5);
myList.push_back(a);
/* If I comment out the following line there will be no crash! */
myList.~list();

Simple, then comment it out!!! That's because local variables are
destroyed automatically at the end of their scope, namely here when main()
ends.

What you probably ment is myList.clear(); which is again handled by the
destructor. BTW the app causes a memory leak which is not very dangerous
here, because the app. is going to exit anyways, and all the memory is
going back to the OS.



Quote:
return 0;
}


Regards,
-Dhruv.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Gareth Stockwell
Guest





PostPosted: Thu Sep 25, 2003 1:44 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote

Hi Bernd,

You seem to be a bit confused as to the nature of a destructor. You
should never have to call a destructor explicitly, using code like
myList.~list(). In the case of on-stack objects (of which your myList
is an example), the destructor is called automatically when the object
goes out of scope - in this case, at the end of the main() function.
If, on the other hand, the list had been created on the heap, using
new, then calling delete on a pointer to the list would invoke the
destructor. Since destructors are designed to be called at the end of
an object's life, most are not written in such a way that permits
multiple calls, so some unpleasant behaviour can result if this
occurs.

So, leave that line commented out and your code is fine. I don't
think I have ever written code using the idiom 'myObj.~Obj()' - but I
would be interested to hear if any others on this list could cite a
case in which it would be valid!

Gareth



[email]bernd_moeller (AT) hotmail (DOT) com[/email] (Mookie) wrote in message news:<47b8e6cd.0309240604.329bd680 (AT) posting (DOT) google.com>...
Quote:
Hi group,

I'm in need of some help. I don't understand why my application is
crashing. I boiled down my source code and now I'm at least able to
point my finger at the list destructor ~list(). The following sample
code mirrors more or less my code and this is also crashing. The
if-condition in my destructor is there on purpose, because in my
application there is a library call to free things up and I musn't
call this if the pointer is NULL.
I'm thankfull if someone could explain to me why the code is crashing,
and why the destructor is called so often (myList should be empty,
should't it?)

#include <list

class Test
{
public:
Test(int a){pt = new int(a);}
Test(const Test& rhs)
{
int tmp = *(rhs.pt);
pt = new int(tmp);
}
~Test()
{
cout << "Destructor was called" << endl;
if (pt !=0)
delete pt;
pt = 0;
}
private:
int* pt;
};

int main()
{
list Test a(5);
myList.push_back(a);
/* If I comment out the following line there will be no crash! */
myList.~list();
return 0;
}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Thu Sep 25, 2003 2:26 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote

On 24 Sep 2003 18:34:22 -0400, [email]bernd_moeller (AT) hotmail (DOT) com[/email] (Mookie) wrote:

Quote:
I'm thankfull if someone could explain to me why the code is crashing,
and why the destructor is called so often (myList should be empty,
should't it?)

It does not exist. There is a difference.

Quote:
int main()
{
list<Test> myList;

This is an automatic variable and will be destructed automatically.

Quote:
Test a(5);
myList.push_back(a);
/* If I comment out the following line there will be no crash! */
myList.~list();

You have destroyed myList, not cleared it. You now have space for an
automatic list which does not contain a list object.

Quote:
return 0;

Destructor called for non-object. KaBOOM!

Either replace the destruction with

myList.clear(); // It exists and is empty

or create a new list there to destroy.

new ((void*)&myList) list<Test>(); // There is a new empty list there

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Thu Sep 25, 2003 3:39 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote

In article <47b8e6cd.0309240604.329bd680 (AT) posting (DOT) google.com>, Mookie
<bernd_moeller (AT) hotmail (DOT) com> writes
Quote:
int main()
{
list<Test> myList;
Test a(5);
myList.push_back(a);
/* If I comment out the following line there will be no crash! */
myList.~list();
return 0;
}
The problem has nothing to do with your implementation of Test, or the

creation of myList. You have explicitly destroyed an auto variable which
is a 'No, No, Never' action. You would get the same error if you wrote:

int main(){
Test t;
t.~Test();
return 0;
}


You simply must not call destructors on automatic (local, on stack or
whatever term you use) objects.

--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Gerhard Menzl
Guest





PostPosted: Thu Sep 25, 2003 7:06 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote

Mookie wrote:

Quote:
I'm in need of some help. I don't understand why my application is
crashing. I boiled down my source code and now I'm at least able to
point my finger at the list destructor ~list(). The following sample
code mirrors more or less my code and this is also crashing. The
if-condition in my destructor is there on purpose, because in my
application there is a library call to free things up and I musn't
call this if the pointer is NULL.

I don't know what you mean exactly by "free things up", but deleting a
null pointer is safe. There is no need to check yourself, as the check
is already built-in.

Quote:
#include <list

class Test
{
public:
Test(int a){pt = new int(a);}
Test(const Test& rhs)
{
int tmp = *(rhs.pt);
pt = new int(tmp);
}
~Test()
{
cout << "Destructor was called" << endl;
if (pt !=0)
delete pt;
pt = 0;
}
private:
int* pt;
};

It is equally pointless to set pt to 0 in the destructor, as it cannot
be legally accessed after that anyway.

Quote:
int main()
{
list Test a(5);
myList.push_back(a);
/* If I comment out the following line there will be no crash! */
myList.~list();
return 0;
}

That's no surprise. Except for the relatively exotic case of in-place
construction, you are *never* supposed to call a destructor explicitly.
myList is an automatic object, hence its destructor will be called
automatically when it goes out of scope at teh end of main(). Calling
the destructor explicitly before that invokes undefined behaviour, which
can mean anything and, in your case, luckily results in a crash.

Quote:
I'm thankfull if someone could explain to me why the code is crashing,
and why the destructor is called so often (myList should be empty,
should't it?)

Which destructor do you mean? The list<Test> destructor? This should be
called once, if it were not for your erroneous extra invocation. Or the
destructor of Test? You should normally see (at least) two invocations
here: one for the instance named a, and one for the copy in the list
that gets destroyed with the container.

Gerhard Menzl


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Tonci Tomic
Guest





PostPosted: Thu Sep 25, 2003 8:40 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote


"Mookie" <bernd_moeller (AT) hotmail (DOT) com> wrote

Quote:
int main()
{
list<Test> myList;
Test a(5);
myList.push_back(a);
/* If I comment out the following line there will be no crash! */
myList.~list();
return 0;
}

You answered your own question. If you don't invoke destructor twice on
myList, everything will be OK.
In you case, destructor is invoked twice. Once explicitly, once at the end
of main body.
Mayby I don't see something obvious but I wonder:
Why did you invoke list destructor explicitly??



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Robert Klemme
Guest





PostPosted: Thu Sep 25, 2003 8:42 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote


"Mookie" <bernd_moeller (AT) hotmail (DOT) com> schrieb im Newsbeitrag
news:47b8e6cd.0309240604.329bd680 (AT) posting (DOT) google.com...
Quote:
int main()
{
list<Test> myList;
Test a(5);
myList.push_back(a);
/* If I comment out the following line there will be no crash! */
myList.~list();

You practically never invoke a destrutor manually. myList is destroyed
automatically at the end of the scope, i.e. after return.

Quote:
return 0;
}

Regards

robert


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ulrich Eckhardt
Guest





PostPosted: Thu Sep 25, 2003 8:49 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote

Mookie wrote:

Quote:
Hi group,

I'm in need of some help. I don't understand why my application is
crashing. I boiled down my source code and now I'm at least able to
point my finger at the list destructor ~list(). The following sample
code mirrors more or less my code and this is also crashing.

Your example violates the requirement of std::list and good
programming-practice to supply an assignment-operator. The new'ed int was
already deleted by a copy but the original's pointer still left pointing
nowhere.

Quote:
The if-condition in my destructor is there on purpose, because
in my application there is a library call to free things up and
I musn't call this if the pointer is NULL.

FYI: You can always call delete on a null-pointer, at least with a
non-broken implementation.

Ulrich Eckhardt


--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Radu Grigore
Guest





PostPosted: Thu Sep 25, 2003 11:29 pm    Post subject: Re: strange behaviour of STL destructor Reply with quote

Quote:
int main()
{
list<Test> myList;
Test a(5);
myList.push_back(a);
/* If I comment out the following line there will be no crash! */
myList.~list();
return 0;
}

AFAIK the standard says that calling a destructor twice is undefined.
And here you call the destructor once explicitely and once implicitely
(because the list is on the stack - auto variable).

Why would you EVER need to call the destructor explicitely? For a STL
container clear() is probably what you want.

regards,
radu
http://www.geocities.com/_rgrig

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Siemel Naran
Guest





PostPosted: Sat Sep 27, 2003 12:40 am    Post subject: Re: strange behaviour of STL destructor Reply with quote

"Erik Max Francis" <max (AT) alcyone (DOT) com> wrote in message

Quote:
The circumstances under which you want to call a destructor explicitly
are extremely rare, and this is a good example why. The list is deleted

So when is an explicit call to the destructor warranted?

--
+++++++++++
Siemel Naran



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Siemel Naran
Guest





PostPosted: Sat Sep 27, 2003 12:42 am    Post subject: Re: strange behaviour of STL destructor Reply with quote

"Ulrich Eckhardt" <doomster (AT) knuut (DOT) de> wrote


Quote:
Your example violates the requirement of std::list and good
programming-practice to supply an assignment-operator. The new'ed int was
already deleted by a copy but the original's pointer still left pointing
nowhere.

Not so. The std::list will use the copy constructor to copy elements. It
cannot construct a default Test object and then set it using Test::operator=
because a default constructor Test::Test() does not exist.

Test(const Test& rhs)
{
int tmp = *(rhs.pt);
pt = new int(tmp);
}

The copy constructor makes a deep copy of the integer, and the destructor
releases it. So there's no memory leak here.

However, it's a good practice to have an assignment operator that does the
right thing, which here is like the copy constructor to make a deep copy.
Never know who might want to use it, as in Test test2 = test1.

--
+++++++++++
Siemel Naran


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.