Visual Studio 2010,C++,vector.clear()中的矢量迭代器不兼容()

问题描述:

由于一些疯狂,我不得不升级到Microsoft Visual Studio 2010 Ultimate,并重新安装了Win7 Pro。我已经将代码缩减为结构的骨架以及通常会发生的事情。我听说这可能是VS2010中STL实现中的一个错误,如果有的话,我正在寻找解决方法。Visual Studio 2010,C++,vector.clear()中的矢量迭代器不兼容()

#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(); 
}; 

而这里的源文件:

这里的头文件:(编辑我的原代码,在Visual Studio 2008中工作得很好)

#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()函数时失败。即使将clear for循环更改为从1,2开始,也会发生这种情况。错误似乎是由.clear()调用.erase(begin(),end())引起的。当矢量中没有放置任何东西时它真的很讨厌它,它已经是空的了。有趣的是,这里是我在擦除时清除循环从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关闭这些“功能”(我真的想知道,如果我不小心搞砸了),任何人有什么想法,究竟是什么原因是和如何解决这个问题?虽然我确实有一些重复的清除,但我不认为这会成为这个问题的根源。特别是考虑到代码从来就不会到达析构函数。

在此先感谢!

〜丹

不知道的意图是什么在这里,但如果你删除this->~ParentClass();它的工作原理。

+0

那么,在这个代码中,这是毫无意义的。在真实的代码中,我发现自己一遍又一遍地写构造函数和析构函数。为了安全起见,我始终将零/零值排除在外,只是觉得键入函数调用会更容易,而不是...用轨迹板复制粘贴。失败。 但是......没有解决这个示例问题。我将不得不看看它是否修复了我的研究的一切!我感到乐观。谢谢吨。这几天我一直在抨击我的头。 – 2012-04-12 05:34:50

+2

你永远不会自己调用析构函数。它不会像你说的那样“清除数据”,它会破坏它。它会删除对象,擦除内存并使指针失效。您可以自己调用析构函数的唯一原因是就地新增了。您应该阅读一些C++基础知识。您应该创建一个名为“重置”的独立函数或者对对象进行软重置并将其保留在可用状态的内容。 – 2012-04-12 06:40:22

ParentClass::ParentClass() 
{ 
    this->~ParentClass(); 
} 

析构函数不是一个正常的函数,它是一个特殊函数。如果你在一个对象上调用析构函数,它将被完全销毁,包括其所有的基础和成员。在完成构造之前,您正在销毁对象ParentClass。任何使用该对象的尝试都可能导致问题,例如您看到的错误消息标记的问题。

如果您想在析构函数和另一个函数之间共享代码,您应该将代码放在单独的函数中,并从析构函数和其他函数中调用该代码。在几乎所有的应用程序代码中,您都不需要明确调用析构函数。

std::vector默认构造为空,并在销毁时清理,因此构造函数和构造函数的构造函数和析构函数都是冗余的,并且可以省略。

+0

所以基本析构函数在编写“delete Object”时被调用。 – 2012-04-12 08:46:06