Topic: standard way to delete all elements in a container?


Author: "Steven S. Wolf" <steve.nospam@crocker.com>
Date: 1999/07/12
Raw View
given a container, what is the 'standard' way to deconstruct it, or to
explicitly remove & delete all contents.

for example:

#include <list>
class foo { };
typedef list<foo*> foolist;

int main()
{
    foolist fl;
    for (int i = 0; i < 50; i++)
        fl.insert(new foo());

    ...
    // how to delete all contents of fl?
}

Two questions really:

1) what is the preferred method of saying
"fl.remove_all_elements_and_destroy_them()"
2) what is the preferred way of adding such a step to the destructor for
class foolist?
--

Steven S. Wolf
Senior Software Architect




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gregory Bond <gnb@itga.com.au>
Date: 1999/07/14
Raw View
"Steven S. Wolf" <steve.nospam@crocker.com> writes:

> given a container, what is the 'standard' way to deconstruct it, or to
> explicitly remove & delete all contents.

All standard container classes will destroy all contained objects when
the container is destroyed.  If you are asking, "how do I destroy all
the contained objects and free all the memory without destroying the
container itself", then the trick
 typedef list<foo> foolist;
 foolist fl;
 //.....
 foolist().swap(fl);
will probably work.

A line like
 fl.erase(fl.begin(), fl.end());
will destroy all the members of fl, but probably much less
efficiently, and may not release memory.  Sequence and associative
containers such as vector<> or set<> have a member function
 fl.clear();
which will do the same thing, perhaps a bit more efficiently.

[Are there any containers that are _not_ sequences or associative?]


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW <allan_w@my-deja.com>
Date: 1999/07/14
Raw View
In article <931802283.860.33@news.remarQ.com>,
  "Steven S. Wolf" <steve.nospam@crocker.com> wrote:
>
> given a container, what is the 'standard' way to deconstruct
> it, or to explicitly remove & delete all contents.

The standard way to deconstruct a container happens automatically
when the container's lifetime ends.

The standard way to "empty" a container, so that all of it's
elements are deleted but the container can be re-used, is

    container.swap(ContainerType());

> for example:
>
> #include <list>
> class foo { };
> typedef list<foo*> foolist;
>
> int main()
> {
>     foolist fl;
>     for (int i = 0; i < 50; i++)
>         fl.insert(new foo());
>
>     ...
>     // how to delete all contents of fl?
> }

This is not a list of foo, it's a list of foo pointers. When the
foolist is deleted, the memory for the foo pointers will be
released but the foos that they point to won't be -- if you
don't have any other pointers, this will be a leak.



> Two questions really:
>
> 1) what is the preferred method of saying
> "fl.remove_all_elements_and_destroy_them()"

If you need to delete all the pointed-to foos, you could use
    foolist::iterator e=fl.end();
    for (foolist::iterator b=fl.begin(); b!=e; ++b)
        delete *b;

> 2) what is the preferred way of adding such a step to the destructor
for
> class foolist?

You could derive from foolist, but I wouldn't recommend it.
A better idea would be to change the typedef of foolist to

    typedef list<foo> foolist;

This will require some minor syntax changes in code that
uses foolist.

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Matt Austern <austern@sgi.com>
Date: 1999/07/14
Raw View
Gregory Bond <gnb@itga.com.au> writes:

> "Steven S. Wolf" <steve.nospam@crocker.com> writes:
>
> > given a container, what is the 'standard' way to deconstruct it, or to
> > explicitly remove & delete all contents.
>
> All standard container classes will destroy all contained objects when
> the container is destroyed.  If you are asking, "how do I destroy all
> the contained objects and free all the memory without destroying the
> container itself", then the trick
>  typedef list<foo> foolist;
>  foolist fl;
>  //.....
>  foolist().swap(fl);
> will probably work.

So will fl.clear(), which is simpler.  The clear() member function was
added relatively late in the standardization process, though, so older
standard library implementations might not have it.

The original poster, however, was (I think) asking: how do I walk
through a container of pointers, all of which are assumed to point to
distinct objects, deleting each of those objects.

The straightforward way is to use a loop.  You could also use
for_each, and you might think that you could combine for_each with
mem_fun, but that doesn't quite work because it's illegal to take the
address of a destructor.  (And besides, you don't just want to invoke
foo::~foo(), you want a delete-expression.) You could write yet
another tiny helper object, though:
        template <class T>
        struct destroyer {
          void operator()(T* t) const { delete t; }
        };
and then you can write:
        for_each(foolist.begin(), foolist.end(), destroyer<foo>());

(Oh, and: why doesn't the destructor for a container of pointers do
that automatically?  Because it's not always correct behavior!  If
you've got a list of pointers, it's probably because they're pointers
to objects that are managed somewhere else.  You might have several
entries, possibly in several lists, pointing to the same object.)



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]