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

Discussion in 'C++' started by jimjim, Apr 14, 2004.

  1. jimjim

    jimjim Guest

    Hello again,
    Consider the following code:

    #include <iostream>
    #include <list>

    class X {
    private:
    int val;
    public:
    X(int v){ cout << "X constructor\n"; val = v;}
    ~X() { cout << "X destructor\n"; }
    X( X const & ) { cout << "X copy constructor\n"; }
    int return_val() {return val;}
    };

    int main(){
    X x(6);
    list<X>lists;
    lists.push_back(x);
    list<X>::iterator i = lists.begin();
    cout << (*i).return_val()<<endl;
    lists.erase(lists.begin());
    }
    The output is as expected:
    X constructor
    X copy constructor
    0
    X destructor
    X destructor

    Why is 0 returned by the return_val() and not 6? I assume when I push the x
    object into the list, I copy both the object and the state.
    jimjim, Apr 14, 2004
    #1
    1. Advertising

  2. jimjim

    Jeff Flinn Guest

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

    "jimjim" <> wrote in message
    news:KUbfc.3426$...
    > Hello again,
    > Consider the following code:
    >
    > #include <iostream>
    > #include <list>
    >
    > class X {
    > private:
    > int val;
    > public:
    > X(int v){ cout << "X constructor\n"; val = v;}
    > ~X() { cout << "X destructor\n"; }
    > X( X const & ) { cout << "X copy constructor\n"; }
    > int return_val() {return val;}
    > };
    >
    > int main(){
    > X x(6);
    > list<X>lists;
    > lists.push_back(x);
    > list<X>::iterator i = lists.begin();
    > cout << (*i).return_val()<<endl;
    > lists.erase(lists.begin());
    > }
    > The output is as expected:
    > X constructor
    > X copy constructor
    > 0
    > X destructor
    > X destructor
    >
    > Why is 0 returned by the return_val() and not 6? I assume when I push the

    x
    > object into the list, I copy both the object and the state.


    Given X's copy constructor, why would you expect it to be 6?

    Jeff F
    Jeff Flinn, Apr 14, 2004
    #2
    1. Advertising

  3. jimjim

    jimjim Guest

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

    thx for the fast reply.

    As I mentioned, I assume that when I push an object into a list I copy the
    whole object (ie the values of its member variables). I guess the copy
    constructor prevents from copying the values that an object had when it is
    copied right?
    jimjim, Apr 14, 2004
    #3
  4. jimjim

    jimjim Guest

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

    > As I mentioned, I assume that when I push an object into a list I copy the
    > whole object (ie the values of its member variables). I guess the copy
    > constructor prevents from copying the values that an object had when it is
    > copied right?
    >

    As if I comment out the copy constructor from the class definition, the
    result is:
    X constructor
    6
    X destructor
    X destructor
    jimjim, Apr 14, 2004
    #4
  5. jimjim

    Leor Zolman Guest

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

    On Wed, 14 Apr 2004 14:55:01 GMT, "jimjim" <>
    wrote:

    >> As I mentioned, I assume that when I push an object into a list I copy the
    >> whole object (ie the values of its member variables). I guess the copy
    >> constructor prevents from copying the values that an object had when it is
    >> copied right?
    >>

    >As if I comment out the copy constructor from the class definition, the
    >result is:
    >X constructor
    >6
    >X destructor
    >X destructor
    >
    >


    When you wrote your own copy constructor, that's the one that was used.
    Your version didn't copy anything, so you got "default initialization"
    behavior: the new object's data member was set to zero (to be honest, I
    never realized that copy ctors would do that, and I haven't yet found where
    in the Standard that behavior is specified. But that's what it seems to be
    doing.)

    When you removed your own definition of the copy ctor, /then/ the compiler
    generated one for you that did a member-wise copy of the class's data
    members, and you got the desired behavior.
    -leor

    --
    Leor Zolman --- BD Software --- www.bdsoft.com
    On-Site Training in C/C++, Java, Perl and Unix
    C++ users: download BD Software's free STL Error Message Decryptor at:
    www.bdsoft.com/tools/stlfilt.html
    Leor Zolman, Apr 14, 2004
    #5
  6. jimjim

    Jeff Flinn Guest

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

    "Leor Zolman" <> wrote in message
    news:...
    > On Wed, 14 Apr 2004 14:55:01 GMT, "jimjim" <>
    > wrote:
    >
    > >> As I mentioned, I assume that when I push an object into a list I copy

    the
    > >> whole object (ie the values of its member variables). I guess the

    copy
    > >> constructor prevents from copying the values that an object had when it

    is
    > >> copied right?
    > >>

    > >As if I comment out the copy constructor from the class definition, the
    > >result is:
    > >X constructor
    > >6
    > >X destructor
    > >X destructor
    > >
    > >

    >
    > When you wrote your own copy constructor, that's the one that was used.
    > Your version didn't copy anything, so you got "default initialization"
    > behavior: the new object's data member was set to zero (to be honest, I
    > never realized that copy ctors would do that, and I haven't yet found

    where
    > in the Standard that behavior is specified. But that's what it seems to be
    > doing.)


    I was under the impression that the data member would not be initialized at
    all, and that the zero was just luck. Or if the op's code was compiled in
    debug, on some compilers the memory is set to zero when allocated.

    Jeff F
    Jeff Flinn, Apr 14, 2004
    #6
  7. jimjim

    jimjim Guest

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

    I see thx :)

    so how could I copy the values of the variables to the copy object?
    jimjim, Apr 14, 2004
    #7
  8. Re: why it seems that std::list::erase() doesnt free objects in a list, if the latter holds pointers to them?

    "jimjim" <> wrote in message
    news:jtefc.3567$...
    > I see thx :)
    >
    > so how could I copy the values of the variables to the copy object?
    >


    X( X const & rhs) : val(rhs.val) { cout << "X copy constructor\n"; }

    and your other constructor should be

    X( int v) : val(v) { cout << "X constructor\n"; }

    Its a good habit to get into using val(rhs.val) and val(v) instead of val =
    rhs.val and val = v. The first is called initialisation and the second is
    called assignment. In general initialisation is more efficient than
    assignment.

    john
    John Harrison, Apr 14, 2004
    #8
  9. jimjim

    Jeff Flinn Guest

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

    "jimjim" <> wrote in message
    news:jtefc.3567$...
    > I see thx :)
    >
    > so how could I copy the values of the variables to the copy object?


    Lookup copy constructor in any C++ book or the FAQ. You should also learn to
    use initializer lists. Even though you should really do this yourself,
    here's your original class reworked.

    class X
    {
    int mVal;

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

    X( ):mVal( 0){ cout << "X default
    constructor\n"; }
    X( int aVal ):mVal( aVal){ cout << "X constructor\n"; }
    X( X const& aRef ):mVal(aRef.mVal){ cout << "X copy constructor\n"; }

    int return_val()const{ return mVal; }
    };

    Note the added default constructor, and the explicit initialization of the
    data member in each constructor. In your original code the mVal() initilizer
    list was automatically provided by the compiler. When you removed the
    defective copy constructor, the compiler supplied an equivalent copy
    constructor to the one shown above.

    Jeff F
    Jeff Flinn, Apr 14, 2004
    #9
  10. jimjim

    Leor Zolman Guest

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

    On Wed, 14 Apr 2004 12:27:45 -0400, "Jeff Flinn" <>
    wrote:

    >>
    >> When you wrote your own copy constructor, that's the one that was used.
    >> Your version didn't copy anything, so you got "default initialization"
    >> behavior: the new object's data member was set to zero (to be honest, I
    >> never realized that copy ctors would do that, and I haven't yet found

    >where
    >> in the Standard that behavior is specified. But that's what it seems to be
    >> doing.)

    >
    >I was under the impression that the data member would not be initialized at
    >all, and that the zero was just luck. Or if the op's code was compiled in
    >debug, on some compilers the memory is set to zero when allocated.


    I didn't try it with enough compilers. Although things got set to zero with
    the first few I tried (no debug mode, and I even changed the type of the
    variable in question to double, just to see if that made any
    difference...and it didn't on those few platforms), as soon as I tried a
    few more compilers just now, things went quickly to hell in a hand basket.

    I'm actually glad, because I would have felt stupider if that /was/ the
    required behavior of copy constructors and I hadn't known it...
    -leor

    >
    >Jeff F
    >


    --
    Leor Zolman --- BD Software --- www.bdsoft.com
    On-Site Training in C/C++, Java, Perl and Unix
    C++ users: download BD Software's free STL Error Message Decryptor at:
    www.bdsoft.com/tools/stlfilt.html
    Leor Zolman, Apr 14, 2004
    #10
  11. jimjim

    jimjim Guest

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

    thank you both :)
    jimjim, Apr 14, 2004
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jimjim
    Replies:
    18
    Views:
    7,337
    Default User
    Apr 12, 2004
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,761
    Smokey Grindel
    Dec 2, 2006
  3. jimjim
    Replies:
    16
    Views:
    822
    Jordan Abel
    Mar 28, 2006
  4. erase vs. erase

    , Mar 25, 2006, in forum: C++
    Replies:
    7
    Views:
    354
    Pete Becker
    Mar 30, 2006
  5. Replies:
    3
    Views:
    325
    terminator
    Mar 25, 2007
Loading...

Share This Page