2

I have a vector (pflist) of "Pictureframe"s, and I want to destroy all of them. So I run pflist.clear(); The documentation says that this runs the destructor of each item in the vector, but it isn't!

I have a:

vector<Pictureframe*> pflist;

And here's the rest:

class Pictureframe{
    scene::IMeshSceneNode *picture;
    scene::IMeshSceneNode *frame;

public:
    Pictureframe();
    ~Pictureframe();
};

and then in the cpp file:

Pictureframe::~Pictureframe(){
//  delete picture;
//  delete frame;
    cout<<"Destructor Called.\n\n";
}

There is nary a "Destructor Called" in sight! Here's where I call it:

pflist.clear();

I am sure that this line is being run, and that is populated by 5 pictureframes. I also tried a for loop that went through the vector pop_back'ing, and that had the same problem.

So Destructor, Y U NO CALL?

Magicaxis
  • 371
  • 7
  • 16

2 Answers2

7

Your question doesn't state what the type of the std::vector is. If the type is std::vector<Pictureframe *> then the destructors of each element will not be called when you call std::vector::clear. In this case it is your responsibility to delete these objects before clearing the vector.

If you don't need to dynamically allocate these objects, change the vector type to std::vector<Pictureframe>. Use it as:

std::vector<Pictureframe> vec;
vec.push_back( Pictureframe( ... ) );
// do stuff
vec.clear();

Now the destructor for each object will be called. Remember to create a copy constructor and assignment operator for Pictureframe since it looks like the class is managing some resources.

If you must dynamically allocate Pictureframe objects, change the vector to

std::vector<std::unique_ptr<Pictureframe>> vec;
vec.push_back( std::unique_ptr<Pictureframe>( new Pictureframe( ... ) ) );
// do stuff
vec.clear();

unique_ptr will automatically delete the objects in this case.

Other alternatives are boost::shared_ptr instead of std::unique_ptr or boost::ptr_vector.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Thank you so much for the thoroughness of this answer, you were spot on, and its fixed! Muchos Gracias Senor – Magicaxis May 22 '12 at 06:47
  • 3
    More correctly, the destructor of each element in the container _will_ be run. The destructor of a pointer is a no-op, however. – James Kanze May 22 '12 at 07:38
2

I am pretty much sure you have an std::vector<Pictureframe *>
Any standard library container does not take the responsibility of clearing dynamically allocated pointer elements.

You will have to iterate through the std::vector and call delete on each of the elements.

This answer of mine to an old question should be a good read:
Does vector::erase() destroy the removed object?

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533