由于一些疯狂,我被迫在全新安装的Win7 Pro上升级到Microsoft Visual Studio 2010 Ultimate。我已经将代码简化为结构的基础,以及一般情况下正在发生的事情。我听说这可能是VS2010在他们的STL实现中的一个错误,如果是这样,我正在寻找解决方法。 (编辑:我的原始代码在Visual Studio 2008中运行良好。)
这是头文件:
#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();
};
这是源文件:
#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);
}
在发布版中进行编译可以提供可预测且功能正常的内容:
(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
在调试模式下编译给出:
(blank)
0
0 1
0 1 2
0 1 2 3
Debug Assertion Failed... vector iterators incompatible.
第一次调用 .Clear()函数时失败。即使将清除for循环更改为从1,2开始等,也会发生这种情况。错误似乎是因为.clear()调用.erase(begin(),end())。当向量中没有放入任何内容并且它已经为空时,它真的很讨厌它。有趣的是,这是我在autos中看到的,当清除循环在擦除时从2开始(const_iterator _First_arg,const_iterator_Last_arg)。
_First_arg = 0,正如所料。
_Last_arg = -2.53 ... e-098
这样:
尺寸:2
容量:2
0:0.0000 ......
1:1.000 ....
第一个向量从:0x002648e8开始 最后一个向量开始于:0x002648f8(虽然我认为由于end(),这实际上是一个超出最后一个,这对于8个字节的双精度来说是有意义的。)
除了转到预处理器定义并设置_ITERATOR_DEBUG_LEVEL = 0以关闭这些“功能”(我实际上想知道我是否意外搞砸了),任何人都有任何想法,实际原因是什么以及如何解决这个问题?虽然我确实有一些多余的清除,但我认为这不会成为这个问题的根源。特别是考虑到代码从来没有首先进入析构函数。
提前致谢!
〜丹
答案 0 :(得分:2)
ParentClass::ParentClass()
{
this->~ParentClass();
}
析构函数不是正常函数,它是一个特殊函数。如果在对象上调用析构函数,它将被完全销毁,包括其所有基础和成员。在这里,您将在ParentClass
对象完全构建之前销毁它。任何使用该对象的尝试都可能导致问题,例如您看到的错误消息所标记的问题。
如果你想在析构函数和另一个函数之间共享代码,你应该将代码放在一个单独的函数中,并从析构函数和其他函数中调用它。在几乎所有应用程序代码中,您都不需要显式调用析构函数。
默认情况下, std::vector
被构造为空并且在销毁时清除,因此ChildClass
构造函数和ParentClass
构造函数和析构函数在您的示例中都是多余的,可以省略。
答案 1 :(得分:1)
不确定这里的目的是什么,但是如果你移除this->~ParentClass();
就行了。