The problem is not with vector, it's with your class. Your class is doing a shallow copy.
Here's your problem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
int main()
{
{
Foo a; // <- 'a' creates a new int for its child.
{
Foo b(a); // <- 'b' is a copy of 'a'. Note that you did not write a copy ctor for
// Foo, so this will do a shallow copy. That is... a.child and b.child point to the same
// memory.
} // <- 'b's destructor is called. b.child is deleted
// at this point, a.child is a BAD POINTER because it was deleted when b's destructor
// deleted it (remember both pointers pointed to the same data)
} // <- a's dtor called... a.child is deleted AGAIN. This is where you are crashing
}
|
This is happening with vector because vector sometimes has to move the memory around when you resize it, in order to keep all elements continuous in memory.
Possible Solutions (in the order in which I recommend them):
1) Don't use dynamic allocation
There's no need for it here. 'child' does not have to be a pointer. You can just make it a normal int and remove the dtor completely and remove the 'new' from the ctor.
2) If you must use dynamic allocation, use a smart pointer
unique_ptr will take care of deletion and copying/moving effects so you don't have to worry about them.
1 2 3 4 5 6 7 8 9 10
|
class Foo{
public:
std::unique_ptr<int> child;
Foo(){
if(rand()%10) child = std::unique_ptr<int>( new int(5) );
}
// no need for the dtor... unique_ptr will take care of deletion for you
};
|
3) Write a proper copy constructor + assignment operator and/or move constructor + move assignment operator.
The copy constructor and assignment operators would need to do a deep copy of the 'child' member (ie: allocate new memory and copy the pointed-to data... rather than just copying the pointer).
But as this is error prone and a lot of work... it's best to avoid this.
Typically... if you're managing memory yourself... you're probably doing it wrong.
EDIT:
ninja'd by Cubbi.