std::vector push_back() corruption

Started by
10 comments, last by Mantear 18 years, 3 months ago
I've created a class. I'm going to have multiple instances of this class (they are check box widgets for a GUI). When I add a new check box, I create a new instance of the class and try to put it into a vector of check boxes using push_back(). However, I'm getting some data corruption. The class inherits from a base class. It implements some additional functions and two extra public member variables, one is a bool pointer, the other is a function pointer to a function that takes a boolean as a parameter. When I call the push_back() onto the vector, the last data element is not properly copied. If I declare the function pointer last in the class declaration, it is not copied (the original instance being used has the pointers being set to NULL) and contains 0xdfdfdfdf/whatever. If I declare the bool pointer last, it becomes corrupted and the function pointer is fine. In other words, it appears that the push_back() function does not like instances of my class. When I try to call push_back() for the second time, I get a runtime error that shows up in the xmemory file. I have another class that is similar (a button widget) that has a function pointer to a function with no parameters as the last item declared in the class. This one appears to work fine. Any ideas?
Advertisement
What compiler are you using?
Have you defined a copy constructor for the class? When you push_back() an object to a std::vector, you are actually making a copy of the object and storing the copy in the vector.
do you have a an std::vector of <BaseClassgt;? If so, you are probably encountering object slicing. Use a vector of BaseClass or DerivedClass pointers instead.

WillF - I'm not sure if defining a copy constructor will be enough, because the copy constructor is called on the object's static type. If his container is a vector of BaseClass objects, he's going to have a problem.
Also, are you trying to store a derived class in a vector of base class objects. Or is it a vector of base class pointers (or even better boost::shared_ptr s)?

Or to put it another way are you using
std::vector<base>
or
std::vector<base*>
Quote:Original post by ITGER
WillF - I'm not sure if defining a copy constructor will be enough, because the copy constructor is called on the object's static type. If his container is a vector of BaseClass objects, he's going to have a problem.


You're right... I didn't pay enough attention to his post.

To the OP, if you're going to use a vector of pointers you'll probably be happier with either boost::shared_ptr or boost::ptr_vector

There's some info on using shared_ptr in this article: Using Modern C++ to Eliminate Memory Problems
I'm using C++/MSVC 2005 Express.

The vector is of the derived class. Basically, I'm doing std::vector<CheckBoxWidgets>. The vector is not a vector of the base class, and I'm storing entire objects, not pointers (they're only around 100 bytes large, will only be generated upon program init, etc, so it doesn't hurt to copy the whole thing). Do I need to create my own 'operator=' to make sure it copies correctly when the push_back is called?
I think it would help if we could see the actual class definition for both the base and derived class(es).
Here's the source
class GUIBaseObject{public:   GUIBaseObject::GUIBaseOBject();   GUIBaseObject::~GUIBaseOBject();   void DrawBackGround();   void DrawBackGroundTransparent();   void DrawBorder();   virtual void DrawGUIItem();   virtual void DrawPickingGUIItem();   void DrawOutline();   void DrawText(string text);   unsigned int GetHeight();   unsigned int GetWidth();   void SetBGColor(unsigned char color[4]);   void SetBorderColor(unsigned char color[4]);   void SetLocation(int top, int bottom, int left, int right);   void SetTextColor(unsigned char color[4]);      eWidgetType m_WidgetType;   unsigned int m_PickingID;   bool m_Hidden;   bool m_HiddenBorder;   bool m_HiddenBackGround;   sCorners m_Location;   unsigned char m_BGColor[4];   unsigned char m_BorderColor[4];   unsigned char m_TextColor[4];   string m_Title;   bool m_PreSelected;};

class GUICheckBox : public GUIBaseObject{public:   GUICheckBox::GUICheckBox();   GUICheckBox::~GUICheckBox();   void DrawGUIItem();   void DrawPickingGUIItem();   void CallFunction(bool var1);   void DefaultFunction(bool var1);   void TestFunction(bool var1);   void (GUICheckBox::*m_FunctionPtr)(bool var1);   bool* m_pLinkedValue;};


Now, in my main GUI class, I make a vector of 'GUICheckBox's, and am calling push_back() on it.
Quote:Original post by Mantear
Do I need to create my own 'operator=' to make sure it copies correctly when the push_back is called?
Push_back relies on the copy constructor rather than operator =. As to whether you need either of them, I suggest the rule of three: if you have a non-empty destructor (I assume you do, looking at your class declarations), you should write an assignment operator and copy constructor as well.

If, for some reason, you can't write an assignment operator or copy constructor, you can avoid accidents by declaring them as private and never implementing them; but in that case you'd have to store pointers in your vector.
My destructor is empty.

This topic is closed to new replies.

Advertisement