Deleting elements of vectors that contain pointers to other objects

Discussion in 'C++' started by dwightarmyofchampions@hotmail.com, Mar 19, 2009.

  1. Guest

    How exactly do I delete elements of a vector in the destructor?
    Suppose my vector in my class definition looks like this:

    std::vector<ABC*> vec;

    which means I am declaring a vector whose elements will contain
    pointer to ABC objects.

    ....and in my constructor I have:

    vec.clear(); // make sure vector is empty before populating it

    for (int i = 0; i < 5; i++)
    {
    ABC* abcobject1 = new ABC(i);
    vec.push_back(abcobject1);
    }

    When I go to my destructor, do I just need to pop_back() the vector
    elements...

    for (int i = 0; i < 5; i++)
    {
    vec.pop_back();
    }

    ....or do I delete each ABC object and then pop_back its corresponding
    vector pointer...

    for (int i = 0; i < 5; i++)
    {
    delete vec; vec = 0; // or is it (*vec)???
    vec.pop_back();
    }

    ....or do I do something else? Isn't there a delete[] statement for
    this sort of thing?
     
    , Mar 19, 2009
    #1
    1. Advertising

  2. red floyd Guest

    Re: Deleting elements of vectors that contain pointers to otherobjects

    On Mar 19, 9:39 am, wrote:
    > How exactly do I delete elements of a vector in the destructor?
    > Suppose my vector in my class definition looks like this:
    >
    > std::vector<ABC*> vec;
    >
    > which means I am declaring a vector whose elements will contain
    > pointer to ABC objects.
    >
    > ...and in my constructor I have:
    >
    > vec.clear();   // make sure vector is empty before populating it
    >
    > for (int i = 0; i < 5; i++)
    > {
    >   ABC* abcobject1 = new ABC(i);
    >   vec.push_back(abcobject1);
    >
    > }
    >
    > When I go to my destructor, do I just need to pop_back() the vector
    > elements...
    >
    > for (int i = 0; i < 5; i++)
    > {
    >   vec.pop_back();
    >
    > }
    >
    > ...or do I delete each ABC object and then pop_back its corresponding
    > vector pointer...
    >
    > for (int i = 0; i < 5; i++)
    > {
    >    delete vec; vec = 0; // or is it (*vec)???
    >    vec.pop_back();
    >
    > }
    >
    > ...or do I do something else? Isn't there a delete[] statement for
    > this sort of thing?


    This is a question of ownership. That's why you need to document who
    owns what. If the vector is intended to own the pointers, you
    probably shouldn't store raw pointer, but instead use your favorite
    smart pointer.

    If you're using raw pointers, you need to delete the elements
    individually.

    for (std::vector<ABC*>::iterator it = vec.begin();
    it != vec.end();
    ++it)
    {
    delete *it;
    *it = 0; // probably optional
    }

    If you're using smart pointers, where smart_ptr_t<> is your favorite
    smart pointer:

    std::vector<smart_ptr_t<ABC> > vec;
    Then, when vec is deleted, it invokes the smart_ptr_t<> destructor on
    every element,
    and the smart_ptr_t<> destructor handles the memory management.
     
    red floyd, Mar 19, 2009
    #2
    1. Advertising

  3. Guest

    Re: Deleting elements of vectors that contain pointers to otherobjects

    Thanks, that was very helpful.

    I've never even heard of smart pointers, so I'll have to wait on that
    one.

    Question about the iterator for loop: It doesn't delete the vector and
    it doesn't remove the vector elements. Instead, it deletes the objects
    that the vector elements point to. Now my question is, Within the for
    loop do I also have to put in a vec.pop_back(); so the elements
    themselves get deleted? Or will they just automatically get deleted?
    And what about the vec instance itself? Do I have to worry about
    that?

    red floyd wrote:
    > This is a question of ownership. That's why you need to document who
    > owns what. If the vector is intended to own the pointers, you
    > probably shouldn't store raw pointer, but instead use your favorite
    > smart pointer.
    >
    > If you're using raw pointers, you need to delete the elements
    > individually.
    >
    > for (std::vector<ABC*>::iterator it = vec.begin();
    > it != vec.end();
    > ++it)
    > {
    > delete *it;
    > *it = 0; // probably optional
    > }
    >
    > If you're using smart pointers, where smart_ptr_t<> is your favorite
    > smart pointer:
    >
    > std::vector<smart_ptr_t<ABC> > vec;
    > Then, when vec is deleted, it invokes the smart_ptr_t<> destructor on
    > every element,
    > and the smart_ptr_t<> destructor handles the memory management.
     
    , Mar 19, 2009
    #3
  4. James Kanze Guest

    Re: Deleting elements of vectors that contain pointers to otherobjects

    On Mar 19, 5:46 pm, red floyd <> wrote:
    > On Mar 19, 9:39 am, wrote:
    > > How exactly do I delete elements of a vector in the
    > > destructor? Suppose my vector in my class definition looks
    > > like this:


    > > std::vector<ABC*> vec;


    > > which means I am declaring a vector whose elements will
    > > contain pointer to ABC objects.


    > > ...and in my constructor I have:


    > > vec.clear(); // make sure vector is empty before populating it


    > > for (int i = 0; i < 5; i++)
    > > {
    > > ABC* abcobject1 = new ABC(i);
    > > vec.push_back(abcobject1);
    > > }


    > > When I go to my destructor, do I just need to pop_back() the
    > > vector elements...


    > > for (int i = 0; i < 5; i++)
    > > {
    > > vec.pop_back();
    > > }


    > > ...or do I delete each ABC object and then pop_back its
    > > corresponding vector pointer...


    > > for (int i = 0; i < 5; i++)
    > > {
    > > delete vec; vec = 0; // or is it (*vec)???
    > > vec.pop_back();
    > > }


    > > ...or do I do something else? Isn't there a delete[]
    > > statement for this sort of thing?


    > This is a question of ownership. That's why you need to
    > document who owns what. If the vector is intended to own the
    > pointers, you probably shouldn't store raw pointer, but
    > instead use your favorite smart pointer.


    Sort of. If the objects in question have value semantics, and
    support copy, then he probably shouldn't have a vector of
    pointers to begin with. If they are entity objects, then you
    have to ask the question of what their lifetime should be. In
    practice, cases where the lifetime of an entity object depends
    on the lifetime of a container are extremely rare.

    If the lifetime does depend strictly on the container of course,
    then you need to wrap the container in a class which takes care
    of the deletes.

    > If you're using raw pointers, you need to delete the elements
    > individually.


    > for (std::vector<ABC*>::iterator it = vec.begin();
    > it != vec.end();
    > ++it)
    > {
    > delete *it;
    > *it = 0; // probably optional
    > }


    Actually, formally speaking, even that's undefined behavior.
    Formally, you can't touch the vector once you've done the
    delete; you have to erase the element, or replace it with a null
    pointer, first.

    Practically, if this code is in the destructor of the object
    containing the vector, I wouldn't worry about it.

    > If you're using smart pointers, where smart_ptr_t<> is your
    > favorite smart pointer:


    > std::vector<smart_ptr_t<ABC> > vec;
    > Then, when vec is deleted, it invokes the smart_ptr_t<>
    > destructor on every element, and the smart_ptr_t<> destructor
    > handles the memory management.


    Supposing it's that type of smart pointer:). (Don't forget
    that smart pointers are used for other things, such as managing
    locks.) This is a workable solution, but it's usually overkill,
    and you have to pay attention to the semantics of the
    smart_ptr---those which would seem to have the appropriate
    semantics (e.g. auto_ptr) often don't work in containers.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Mar 19, 2009
    #4
  5. James Kanze Guest

    Re: Deleting elements of vectors that contain pointers to otherobjects

    On Mar 19, 9:49 pm, Duke Robillard <> wrote:
    > On Thu, 19 Mar 2009 11:07:29 -0700, dwightarmyofchampions wrote:
    > > I've never even heard of smart pointers, so I'll have to
    > > wait on that one.


    > You should check 'em out; they're wonderful. I've just
    > recently used Boost's shared_ptr.hpp for the first time, and
    > it was great for this kind of thing. Maybe the coding almost
    > as nice as it would be in Java. :)


    For trivial cases, perhaps. For any real applications, it's a
    guaranteed recepe for memory leaks and accessing already freed
    memory.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Mar 19, 2009
    #5
  6. Re: Deleting elements of vectors that contain pointers to otherobjects

    * James Kanze:
    > On Mar 19, 9:49 pm, Duke Robillard <> wrote:
    >> On Thu, 19 Mar 2009 11:07:29 -0700, dwightarmyofchampions wrote:
    >>> I've never even heard of smart pointers, so I'll have to
    >>> wait on that one.

    >
    >> You should check 'em out; they're wonderful. I've just
    >> recently used Boost's shared_ptr.hpp for the first time, and
    >> it was great for this kind of thing. Maybe the coding almost
    >> as nice as it would be in Java. :)

    >
    > For trivial cases, perhaps. For any real applications, it's a
    > guaranteed recepe for memory leaks and accessing already freed
    > memory.


    All righty (or rather, not, but...), you use the Boehm garbage collector, and as
    I understand it you use strict hierarchical ownership and strict adherence to
    conventions for that (for other resources than memory), and it works for you.

    And it would be wonderful (hope that's not too femmy language) if you could put
    up a short tutorial or something on that. Because statistically speaking almost
    no-one else -- in fact, I know only about you -- have managed this. And I
    think that when the steep & long learning curve one fears is present, is
    removed, it could be Really Useful.

    But having mastered such a difficult but quite probably very elegant and
    efficient technique, I find it incredible that you have problems with smart
    pointers, or that your co-workers have. If it's you, then it just doesn't make
    sense, it's sort of impossible. And if it's your co-workers, well then, how the
    heck do they then manage do to things right when they have to do all non-memory
    lifetime management manually (as with garbage collection sans smart pointers)?


    Wondering,

    - Alf

    --
    Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
    No ads, and there is some C++ stuff! :) Just going there is good. Linking
    to it is even better! Thanks in advance!
     
    Alf P. Steinbach, Mar 19, 2009
    #6
  7. Ian Collins Guest

    Re: Deleting elements of vectors that contain pointers to otherobjects

    James Kanze wrote:
    > On Mar 19, 9:49 pm, Duke Robillard <> wrote:
    >> On Thu, 19 Mar 2009 11:07:29 -0700, dwightarmyofchampions wrote:
    >>> I've never even heard of smart pointers, so I'll have to
    >>> wait on that one.

    >
    >> You should check 'em out; they're wonderful. I've just
    >> recently used Boost's shared_ptr.hpp for the first time, and
    >> it was great for this kind of thing. Maybe the coding almost
    >> as nice as it would be in Java. :)

    >
    > For trivial cases, perhaps. For any real applications, it's a
    > guaranteed recepe for memory leaks and accessing already freed
    > memory.


    Um, just about every non-trivial application I've written over the past
    few years (some running 24/7 managing business critical servers) make
    extensive use of smart pointers. None leak or access already freed
    memory.

    I must be doing something wrong.

    --
    Ian Collins
     
    Ian Collins, Mar 20, 2009
    #7
  8. James Kanze Guest

    Re: Deleting elements of vectors that contain pointers to otherobjects

    On Mar 20, 12:02 am, "Alf P. Steinbach" <> wrote:
    > * James Kanze:


    > > On Mar 19, 9:49 pm, Duke Robillard <> wrote:
    > >> On Thu, 19 Mar 2009 11:07:29 -0700, dwightarmyofchampions wrote:
    > >>> I've never even heard of smart pointers, so I'll have to
    > >>> wait on that one.


    > >> You should check 'em out; they're wonderful. I've just
    > >> recently used Boost's shared_ptr.hpp for the first time,
    > >> and it was great for this kind of thing. Maybe the coding
    > >> almost as nice as it would be in Java. :)


    > > For trivial cases, perhaps. For any real applications, it's
    > > a guaranteed recepe for memory leaks and accessing already
    > > freed memory.


    > All righty (or rather, not, but...), you use the Boehm garbage
    > collector,


    When I can. For a number of reasons, that's not as often as I'd
    like.

    > and as I understand it you use strict hierarchical ownership
    > and strict adherence to conventions for that (for other
    > resources than memory), and it works for you.


    No, I don't use a strict hierarchical ownership. In most cases,
    dynamically allocated objects own themselves, and assume the
    responsibility for managing their lifetime.

    > And it would be wonderful (hope that's not too femmy language)
    > if you could put up a short tutorial or something on that.
    > Because statistically speaking almost no-one else -- in
    > fact, I know only about you -- have managed this.


    Are you kidding. I've worked on a number of projects, in a
    number of different companies and organizations, and I've never
    once seen one which used smart pointers when I arrived. I've
    been the one which introduced them, for the special cases where
    they apply, but generally, the only pointers are this and for
    navigation. The this pointer can't be a smart pointer, and
    there's no need for smart pointers for navigation.

    Having heard so much good about Boost::shared_ptr, I did try to
    introduce it into one application. The result was that we
    immediately started leaking memory (due to cycles). And it's
    far too easy to end up with two counters for a single
    object---in cases where a reference counted pointer is
    appropriate (which aren't as many as people seem to think), an
    invasive pointer which stores the counter in the pointed to
    object is far safer.

    > And I think that when the steep & long learning curve one
    > fears is present, is removed, it could be Really Useful.


    > But having mastered such a difficult but quite probably very
    > elegant and efficient technique, I find it incredible that you
    > have problems with smart pointers, or that your co-workers
    > have.


    Incredible or not, those are the facts.

    > If it's you, then it just doesn't make sense, it's sort of
    > impossible. And if it's your co-workers, well then, how the
    > heck do they then manage do to things right when they have to
    > do all non-memory lifetime management manually (as with
    > garbage collection sans smart pointers)?


    Well, smart pointers don't work when the lifetime has to be
    explicitly managed, and is arbitrary. And in other cases, you
    don't use dynamic allocation (except in such low level things
    like string and vector---but since the pointers are internal to
    the object, you don't need smart pointers there). There are
    certainly exceptions---I generally design my agents so that they
    are managed by an invasive smart pointer. But they're just
    that, exceptions.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Mar 20, 2009
    #8
    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. Replies:
    5
    Views:
    2,995
    Earl Purple
    Dec 18, 2005
  2. Mike
    Replies:
    6
    Views:
    315
    James Kanze
    Jan 9, 2010
  3. Roger Pack
    Replies:
    3
    Views:
    168
    Roger Pack
    Sep 28, 2010
  4. Jason Carlton
    Replies:
    11
    Views:
    253
    Dr J R Stockton
    Dec 8, 2009
  5. Replies:
    16
    Views:
    1,005
Loading...

Share This Page