cpp_noname
cpp_noname

Reputation: 2071

Memory Leaks without calling clear() on C++ STL container objects

Suppose that I have a class Foo defined as follows. If I don't have bars.clear() in ~Foo(), will this result in memory leaks? I was wondering about this because bars is an object field ( not a pointer field ) so when ~Foo() is called, the destructor of std::vector should be automatically called so I was wondering whether the destructor of std::vector will transparently call .clear() or not.

    class Foo
    {
      private:
        std::vector<Bar*> bars;//object field

      ...
    };


    Foo::~Foo
    {
      //bars.clear();
    }

Upvotes: 2

Views: 558

Answers (3)

G&#246;sta
G&#246;sta

Reputation: 21

If you hope to protect yourself against memory leaks by calling the clear() method, then I have to disappoint you. If you use a vector with pointers you need to do something like this:

std::vector<Bar*> bars;
bars.push_back(new Bar());
// some work with bars
//  ....
// end of bars usage:
// (probably inside ~Foo() )
for(int i=0; i<bars.size(); i++) delete bars[i];

Depending on your level of experience and your specific use-case you might be better of using:

   std::vector<Bar> bars;

If you want to know whether the std::vector<...>::clear() method is called from within the destructor of the vector, then the answer is: Maybe but not necessarily and it really doesn't matter anyway.

If you're really curious, you might be able to check, what a destructor of a container class does by looking at the header file for the vector container template. If and how much implementation details of std library objects are visible to the user is highly dependant on the system you're running with. At work I happen to work on Solaris 10 machines. The std lib on those machines is an implementation from Hewlett Packard anno 1994, where a lot of the actual code used by the vector template is still visible:

~vector ()
{ 
  __destroy(__start, __finish); 
  __value_alloc_type va(__end_of_storage);
  va.deallocate(__start,__end_of_storage.data()-__start);
}
void clear()
{
  erase(begin(),end());
}
iterator erase (iterator first, iterator last)
{
  iterator i = copy(last, end(), first);
  iterator tmp = __finish;
  __finish = __finish - (last - first); 
  __destroy(i, tmp);
  return first;
}

Upvotes: -1

Steephen
Steephen

Reputation: 15824

std::vector::clear() delete the objects within std::vector and change its std::vector::size() to zero. If you create std::vector, RAII will take care resource release process but you have to wait until reach the out of scope of the vector. If before going out of scope, you need to clean up your vector you can use std::vector::clear().

But in your special case you are keeping pointer to objects inside std::vector, so RAII do delete the pointer but ignores the objects pointing to the pointer. So you have to do your own clean up for the objects pointing to the pointer either before going out of scope and RAII become active or before calling std::vector::clear()

Upvotes: 3

alain
alain

Reputation: 12037

clear() just resets the vector to size 0. It does not delete anything, if the Bar* in the vector bars need to be deleted, you have to do it yourself.

Upvotes: 2

Related Questions