Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » vector.clear() - destructor not called?

Credits go to Matthew Leverton, Schyfis, SiegeLord, and Thomas Fjellstrom for helping out!
This thread is locked; no one can reply to it. rss feed Print
vector.clear() - destructor not called?
Christopher Bludau
Member #5,401
January 2005

Hiho,

I have a class containing the following:

typedef std::vector<CBasicButton*> button_vector_type;

class CButtonMenu
{
private:
  button_vector_type button_list;
...
}

and in the destrutor I have:

CButtonMenu::~CButtonMenu(void)
{
  this->button_list.clear();
}

I have a breakpoint in the destrutor of CBasicButton but it is NOT called...
In the reference I read this:

vector::clear public member function
void clear ( );

Clear content

All the elements of the vector are dropped: their destructors are called, and then they are removed from the vector container, leaving the container with a size of 0.

What did I miss? ???

Matthew Leverton
Supreme Loser
January 1999
avatar

Clearing a vector doesn't free the (pointer) objects inside them, nor does it call their destructors.

SiegeLord
Member #7,827
October 2006
avatar

The elements you are storing are pointers. Pointers have no destructors, they are just addresses to memory elsewhere.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Thomas Fjellstrom
Member #476
June 2000
avatar

Could probably use one of the <algorithm> or whatever functions to do something like: foreach(vec, delete);

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Schyfis
Member #9,752
May 2008
avatar

I figured that out the hard way too.
I would call each element's destructor first and then clear the vector.

________________________________________________________________________________________________________
[freedwill.us]
[unTied Games]

Christopher Bludau
Member #5,401
January 2005

Ok, so the reference and destructor part is only true when the vector contains objects and not pointers. Makes sense.

Which means I have to delete the stuff myself. Just thought that I don't have to when I read the reference.

Thanks!

Schyfis said:

I would call each element's constructor

constructor?

Schyfis
Member #9,752
May 2008
avatar

Typo, destructor.

________________________________________________________________________________________________________
[freedwill.us]
[unTied Games]

bamccaig
Member #7,536
July 2006
avatar

A little smart pointer magic can make it automated.

#include <boost/shared_ptr.hpp>
#include <vector>

typedef boost::shared_ptr<CBasicButton> button_ptr_type;
typedef std::vector<button_ptr_type> button_vector_type;

You shouldn't need to call this->button_list.clear() in your destructor because your button_vector_type property is static. When the CButtonMenu instance is destroyed, the vector and all of its contents will automatically be cleaned up because they're stack allocated. The only concern is whether or not the vector contains dynamically allocated memory, which would need to be deallocated first (which again is where smart pointers come in).

Working example:

main.hpp#SelectExpand
1#ifndef MAIN_HPP 2 #define MAIN_HPP 3 4 #include <boost/shared_ptr.hpp> 5 #include <iostream> 6 #include <vector> 7 8class Example; 9typedef boost::shared_ptr<Example> Example_ptr; 10typedef std::vector<Example_ptr> Example_ptr_vec; 11 12class Example 13{ 14public: 15 int x; 16 17 Example(int); 18 ~Example(void); 19 20 void Print(void) const; 21}; 22 23int main(int, char *[]); 24void test(void); 25 26#endif

main.cpp#SelectExpand
1#include "main.hpp" 2 3int main(int argc, char *argv[]) 4{ 5 std::cout << "Before..." << std::endl; 6 test(); 7 std::cout << "...After." << std::endl; 8 9 return 0; 10} 11 12void test(void) 13{ 14 Example_ptr x; 15 Example_ptr_vec v; 16 17 x.reset(new Example(5)); 18 v.push_back(x); 19 20 v[0]->Print(); 21} 22 23Example::Example(int x): 24 x(x) 25{ 26} 27 28Example::~Example(void) 29{ 30 std::cout << "Example destroyed." << std::endl; 31} 32 33void Example::Print(void) const 34{ 35 std::cout << "Example{x:" << this->x << "}" << std::endl; 36}

[bamccaig@rufus smartptr]$ g++ main.cpp -o smartptr
[bamccaig@rufus smartptr]$ ./smartptr
Before...
Example{x:5}
Example destroyed.
...After.

Go to: