why it seems that std::list::erase() doesnt free objects in a list, if the latter holds pointers to

J

jimjim

Hello,

Consider the following:
class X{
public:
X(){ cout << "X constructor\n"; }
~X() { cout << "X destructor\n"; }
};

int main(){
X x;
list<X>lists;
lists.push_back(x);
lists.erase(lists.begin());
}

the output is:
X constructor //the constructor is called with the statement X x;
X destructor //the destructor is called with the statement
lists.erase(lists.begin()) (??)
X destructor

1. Above, why is the destructor called twice?
2. Does std::list::erase( ) delete both the x object and the Node object in
the list? Should I assume that the Node object in the list holds the object
as a whole as data, or just a pointer to it? Can you please answer with
reference to the implementation of std::list (near which line in the source
code should I look at)?

consider the following changes to main:
int main(){
X *x = new X();
list<X*>lists;
lists.push_back(x);

lists.erase(lists.begin());
}

the output is:
X constructor

3.Why doesn't (or seems that doesn't) lists.erase(lists.begin()) delete the
*x object ? ((I need to use delete (*i) to explicitly free the actual
object))
4. Should I assume that only the Node object in the list is deleted but not
the *x object? Why does this happen? Again, can you please expain with
reference to the implementation of std::list?

Thank you in advance for your help.
 
J

jimjim

P.S: I am using g++ 2.95.2 on solaris (dunno how find the library that I
use in SunOS 5.8)
 
J

jimjim

can't get it! I have changed my class definition but after calling erase
nothing happens
 
J

jimjim

I would appreciate helping me understand why erase doesnt delete the object
when I store a pointer to the object.

Thanks in advance
 
R

Rob Williscroft

jimjim wrote in in
comp.lang.c++:
I would appreciate helping me understand why erase doesnt delete the
object when I store a pointer to the object.

Thanks in advance

#include <iostream>
#include <ostream>
#include <list>

using namespace std;

class X
{
public:
X(){ cout << "X constructor\n"; }
~X() { cout << "X destructor\n"; }
X( X const & ) { cout << "X copy constructor\n"; }

};

int main()
{
X x;
list<X>lists;
lists.push_back(x);
lists.erase(lists.begin());
}

output:

X constructor
X copy constructor
X destructor
X destructor


Note 2 constructors followed by 2 destructors:

The 1st ctor is for local 'x'.
The 2nd ctor is for the *copy* that is pushed into 'lists'.
The first dtor is for the X erased by erase( lists.begin() ).
The last dtor is for local 'x'.

Rob.
 
L

Leor Zolman

I would appreciate helping me understand why erase doesnt delete the object
when I store a pointer to the object.

Erasing an element from a container will apply a destructor to that
element, but raw pointers don't have destructors. If you want pointers to
automatically have a "delete" operation applied to them when you erase them
from an STL container, you have to use a "smart pointer" such as
boost::shared_ptr.
-leor
 
J

jimjim

ha, I now got it :)

So when I push x into the list, I actually create a new copy of the x object
and store it in the list. This means that changing any state of the object
in the list wont affect the object I created with X x; right?
 
R

Rob Williscroft

jimjim wrote in in
comp.lang.c++:
ha, I now got it :)

So when I push x into the list, I actually create a new copy of the x
object and store it in the list. This means that changing any state
of the object in the list wont affect the object I created with X x;
right?

Yup.

Rob.
 
K

Kevin Goodsell

jimjim said:
Hello,

Consider the following:
class X{
public:
X(){ cout << "X constructor\n"; }
~X() { cout << "X destructor\n"; }
};

int main(){
X x;
list<X>lists;
lists.push_back(x);
lists.erase(lists.begin());
}

This code does not compile:

"C:\cygwin\bin\gcc.exe" -W -Wall -Wcast-align -Wwrite-strings
-Wno-sign-compare -Wno-unused-parameter -Wpointer-arith -Wundef
-Wcast-qual -ansi -pedantic-errors -ggdb -c fun.cpp
fun.cpp: In constructor `X::X()':
fun.cpp:3: error: `cout' undeclared (first use this function)
fun.cpp:3: error: (Each undeclared identifier is reported only once for
each
function it appears in.)
fun.cpp: In function `int main()':
fun.cpp:9: error: `list' undeclared (first use this function)
fun.cpp:9: error: syntax error before `>' token
fun.cpp:10: error: `lists' undeclared (first use this function)
Terminated with exit code 1

http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8

-Kevin
 
J

jimjim

:) sorry

#include <iostream.h>
#include <list.h>

class X{
public:
X(){ cout << "X constructor\n"; }
~X() { cout << "X destructor\n"; }
};

int main(){
X x;
list<X>lists;
lists.push_back(x);
lists.erase(lists.begin());
}
 
K

Kevin Goodsell

jimjim said:
:) sorry

#include <iostream.h>
#include <list.h>

class X{
public:
X(){ cout << "X constructor\n"; }
~X() { cout << "X destructor\n"; }
};

int main(){
X x;
list<X>lists;
lists.push_back(x);
lists.erase(lists.begin());
}

OK, and the diagnostics I get from that:

"C:\cygwin\bin\gcc.exe" -W -Wall -Wcast-align -Wwrite-strings
-Wno-sign-compare -Wno-unused-parameter -Wpointer-arith -Wundef
-Wcast-qual -ansi -pedantic-errors -ggdb -c fun.cpp
In file included from /usr/include/c++/3.3.1/backward/iostream.h:31,
from fun.cpp:1:
/usr/include/c++/3.3.1/backward/backward_warning.h:32:2: warning:
#warning This file includes at least one deprecated or antiquated
header. Please consider using one of the 32 headers found in section
17.4.1.2 of the C++ standard. Examples include substituting the <X>
header for the <X.h> header for C++ includes, or <sstream> instead of
the deprecated header <strstream.h>. To disable this warning use
-Wno-deprecated.
Terminated with exit code 0


Neither <iostream.h> nor <list.h> are standard C++ headers. There are
standard C++ headers called <iostream> and <list>, however.

-Kevin
 
L

Leor Zolman

I see. So all X.h are deprecated!

That's correct, but note that "deprecated" is still legal, and probably
will be for a while. Including the .h headers imported from the C library
behaves essentially as if you'd included their cxxxxx modern counterparts,
and followed with a "using namespace std;" that somehow applied just to
stuff in those headers (IOW, you're "injecting" the injectable contents of
those headers into the std namespace).
-leor
 
K

Kevin Goodsell

jimjim said:
I see. So all X.h are deprecated!

thx :)

Not quite. <iostream.h> has never been standard, and therefore cannot be
deprecated. The only X.h that are deprecated are those that are
inherited from C.

-Kevin
 
K

Kevin Goodsell

jimjim said:
I see. So all X.h are deprecated!

thx :)

Also, I think the error message is incorrect:

"Examples include substituting ... <sstream> instead of the deprecated
header <strstream.h>."

As far as I can tell, <strstream.h> is not standard, deprecated or
otherwise. <strstream> is standard but deprecated in favor of <sstream>.

-Kevin
 
K

Kevin Goodsell

Kevin said:
Not quite. <iostream.h> has never been standard, and therefore cannot be
deprecated. The only X.h that are deprecated are those that are
inherited from C.

Actually, I should rephrase that. It's true that all *standard* headers
that end in .h are 1) inherited from C and 2) deprecated. But many .h
headers seen in code posted here are non-standard (either from
pre-standard C++ or non-standard libraries).

-Kevin
 
D

Default User

jimjim said:
I see. So all X.h are deprecated!


No, that's not correct. Old C headers like <stdio.h> are deprecated.
Ones like <iostream.h> are not standard at all and should never be used.




Brian Rodenborn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top