2012-04-12 102 views
1

由於一些瘋狂,我不得不升級到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關閉這些「功能」(我真的想知道,如果我不小心搞砸了),任何人有什麼想法,究竟是什麼原因是和如何解決這個問題?雖然我確實有一些重複的清除,但我不認爲這會成爲這個問題的根源。特別是考慮到代碼從來就不會到達析構函數。

在此先感謝!

〜丹

回答

1

不知道的意圖是什麼在這裏,但如果你刪除this->~ParentClass();它的工作原理。

+0

那麼,在這個代碼中,這是毫無意義的。在真實的代碼中,我發現自己一遍又一遍地寫構造函數和析構函數。爲了安全起見,我始終將零/零值排除在外,只是覺得鍵入函數調用會更容易,而不是...用軌跡板複製粘貼。失敗。 但是......沒有解決這個示例問題。我將不得不看看它是否修復了我的研究的一切!我感到樂觀。謝謝噸。這幾天我一直在抨擊我的頭。 – 2012-04-12 05:34:50

+2

你永遠不會自己調用析構函數。它不會像你說的那樣「清除數據」,它會破壞它。它會刪除對象,擦除內存並使指針失效。您可以自己調用析構函數的唯一原因是就地新增了。您應該閱讀一些C++基礎知識。您應該創建一個名爲「重置」的獨立函數或者對對象進行軟重置並將其保留在可用狀態的內容。 – 2012-04-12 06:40:22

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

析構函數不是一個正常的函數,它是一個特殊函數。如果你在一個對象上調用析構函數,它將被完全銷燬,包括其所有的基礎和成員。在完成構造之前,您正在銷燬對象ParentClass。任何使用該對象的嘗試都可能導致問題,例如您看到的錯誤消息標記的問題。

如果您想在析構函數和另一個函數之間共享代碼,您應該將代碼放在單獨的函數中,並從析構函數和其他函數中調用該代碼。在幾乎所有的應用程序代碼中,您都不需要明確調用析構函數。

std::vector默認構造爲空,並在銷燬時清理,因此構造函數和構造函數的構造函數和析構函數都是冗餘的,並且可以省略。

+0

所以基本析構函數在編寫「delete Object」時被調用。 – 2012-04-12 08:46:06