What is the shortest chunk of C++ you can come up with to safely clean up a vector or list of pointers? (assuming you have to call delete on the pointers?)
list<Foo*> foo_list;
I'd rather not use Boost or wrap my pointers with smart pointers.
What is the shortest chunk of C++ you can come up with to safely clean up a vector or list of pointers? (assuming you have to call delete on the pointers?)
list<Foo*> foo_list;
I'd rather not use Boost or wrap my pointers with smart pointers.
template< typename T >
struct delete_ptr : public std::unary_function<bool,T>
{
bool operator()(T*pT) const { delete pT; return true; }
};
std::for_each( foo_list.begin(), foo_list.end(), delete_ptr<Foo>() );
for(list<Foo*>::const_iterator it = foo_list.begin(); it != foo_list.end(); it++)
{
delete *it;
}
foo_list.clear();
I'm not sure that the functor approach wins for brevity here.
for( list<Foo*>::iterator i = foo_list.begin(); i != foo_list.end(); ++i )
delete *i;
I'd usually advise against this, though. Wrapping the pointers in smart pointers or using a specialist pointer container is, in general, going to be more robust. There are lots of ways that items can be removed from a list ( various flavours of erase
, clear
, destruction of the list, assignment via an iterator into the list, etc. ). Can you guarantee to catch them all?
for (list<Foo*>::const_iterator i = foo_list.begin(), e = foo_list.end(); i != e; ++i)
delete *i;
foo_list.clear();
std::list<T*>
:
while(!foo.empty()) delete foo.front(), foo.pop_front();
std::vector<T*>
:
while(!bar.empty()) delete bar.back(), bar.pop_back();
Not sure why i took front
instead of back
for std::list
above. I guess it's the feeling that it's faster. But actually both are constant time :). Anyway wrap it into a function and have fun:
template<typename Container>
void delete_them(Container& c) { while(!c.empty()) delete c.back(), c.pop_back(); }
It's really dangerous to rely on code outside of the container to delete your pointers. What happens when the container is destroyed due to a thrown exception, for example?
I know you said you don't like boost, but please consider the boost pointer containers.
At least for a list, iterating and deleting, then calling clear at the end is a bit inneficient since it involves traversing the list twice, when you really only have to do it once. Here is a little better way:
for (list<Foo*>::iterator i = foo_list.begin(), e = foo_list.end(); i != e; )
{
list<Foo*>::iterator tmp(i++);
delete *tmp;
foo_list.erase(tmp);
}
That said, your compiler may be smart enough to loop combine the two anyways, depending on how list::clear is implemented.
Since we are throwing down the gauntlet here... "Shortest chunk of C++"
static bool deleteAll( Foo * theElement ) { delete theElement; return true; }
foo_list . remove_if ( deleteAll );
I think we can trust the folks who came up with STL to have efficient algorithms. Why reinvent the wheel?
Actually, I believe the STD library provides a direct method of managing memory in the form of the allocator class:
http://www.cplusplus.com/reference/std/memory/allocator/
You can extend the basic allocator's deallocate() method to automatically delete the members of any container.
I /think/ this is the type of thing it's intended for.