Reputation: 53
Due to some craziness, I've been forced to upgrade to Microsoft Visual Studio 2010 Ultimate on a fresh install of Win7 Pro. I've reduced the code down to bare bones of structure and what in general is going on. I've heard this may be a bug in VS2010 in their STL implementation, and if so, am looking for a work-around. (EDIT: My original code worked fine in Visual Studio 2008.)
Here's the header file:
#include <iostream>
#include <vector>
using namespace std;
class ChildClass //partition function for each
{
public:
ChildClass();
void Clear(void);
vector<double> childrenvars;
void PrintChildren(void);
//long list of other variables
};
class ParentClass
{
public:
ChildClass variable;
//other variables
ParentClass();
~ParentClass();
};
And here's the source file:
#include "source.h"
ChildClass::ChildClass()
{
Clear();
}
void ChildClass::Clear(void)
{
childrenvars.clear();
return;
}
void ChildClass::PrintChildren(void)
{
cout << endl;
for(unsigned int i=0; i<childrenvars.size(); i++)
cout << childrenvars[i] << " ";
}
ParentClass::ParentClass()
{
this->~ParentClass();
}
ParentClass::~ParentClass()
{
this->variable.childrenvars.clear();
}
int main(void)
{
ParentClass* ParVar = new ParentClass[5];
for(unsigned int numiter = 0; numiter < 3; numiter++)
{
for(unsigned int i=0; i<5; i++)
{
for(unsigned int j=0; j<i; j++)
ParVar[i].variable.childrenvars.push_back(j);
ParVar[i].variable.PrintChildren();
}
for(unsigned int i=0; i<5; i++)
ParVar[i].variable.Clear();
}
delete [] ParVar;
int wait;
std::cin >> wait;
return(0);
}
Compiling in release gives a predictable and functional:
(blank)
0
0 1
0 1 2
0 1 2 3
0
0 1
0 1 2
0 1 2 3
0
0 1
0 1 2
0 1 2 3
Compiling in debug mode gives:
(blank)
0
0 1
0 1 2
0 1 2 3
Debug Assertion Failed... vector iterators incompatible.
It is failing on the first time it calls the .Clear() function. This occurs even if changing the clear for loop to start at 1,2, etc. The error seems to be resulting as .clear() calls .erase(begin(), end()). It really hates it when nothing has been put in the vector and it's already empty. Interestingly, here's what I see under the autos when the clear loop starts at 2 in the erase(const_iterator _First_arg, const_iterator_Last_arg).
_First_arg = 0, as expected.
_Last_arg = -2.53...e-098
this:
size: 2
capacity: 2
0: 0.0000...
1: 1.000....
The first vector starts at: 0x002648e8 The last vector starts at: 0x002648f8 (though I think due to the end(), this is actually one beyond the last, which would make sense with 8 byte doubles).
Aside from going to the preprocessor definitions and setting _ITERATOR_DEBUG_LEVEL=0 to turn these "features" off (I actually would like to know if I accidentally do screw up), anybody have any ideas as to what the actual cause is and how to fix this? While I do have some redundant clears in there, I don't imagine that would be the source of this issue. Especially considering the code never even gets to the destructors in the first place.
Thanks in advance!
~Dan
Upvotes: 1
Views: 3894
Reputation: 792637
ParentClass::ParentClass()
{
this->~ParentClass();
}
A destructor is not a normal function, it is a special function. If you call the destructor on an object it is completely destroyed including all its bases and members. Here you are destroying the ParentClass
object before it has been fully constructed. Any attempt to use the object is likely to cause problems such as the one flagged by the error message that you see.
If you want to share code between the destructor and another function you should but the code in a separate function and call that from the destructor and the other function. In almost all application code you should never need to call a destructor explicitly.
std::vector
is constructed empty by default and cleans up on destruction so the ChildClass
constructor and the ParentClass
constructor and destructor are all redundant in your example and can be omitted.
Upvotes: 2
Reputation: 78398
Not sure what the intent is here, but if you remove this->~ParentClass();
it works.
Upvotes: 1