Interestingly, it is because you did not provide an assignment operator. Why do you need one? Well let's think about a vector. The vector object has a pointer to an array of 5 A_class
. They are default constructed, which is no problem since you've defined it. Now we erase:
A_class }
A_class }
A_class }-- Erase one of these
A_class }
A_class }
Interestingly, we don't see a problem if we delete the last one, only if we delete one of indices 0 to 3. Why? Well, when we delete, say, index 2, we get his:
A_class
A_class
-- empty space with size = sizeof(A_class)
A_class
A_class
To reconcile this space, at the end of the erase, std::vector
uses the assignment operator to fix up the array. So index[2] = index[3]
, index[3] = index[4]
. Now, because you didn't declare an assignment operator, it will use the default, which includes deleting of index[4]
. This is bad because index[4]
will give index[3]
its pointer then delete it, resulting in this:
A_class // heap_space okay
A_class // heap_space okay
A_class // heap_space okay
A_class // heap_space deleted! will error when deconstructed
So now when we exit, we attempt to delete index[3]
and everything blows up!
By adding an assignment operator that uses swap
, we can fix the problem:
class A_class
{
public:
//...
// note the byval argument
A_class& operator=(A_class other) {
std::swap(this->heap_space, other.heap_space);
return *this;
}
//...
}