2011-04-28 374 views
0

我有這樣的結構:的std ::矢量斷言失敗(矢量迭代器不兼容)

struct MxMInstanceData 
{ 
    D3DXVECTOR2 mTransform; 
    float mSpacing; 
}; 

然後,我創建MxMInstanceData的向量:

std::vector<MxMInstanceData> instInFrustumData; 

如果我打電話instInFrustumData.clear()我得到這個錯誤:

Assertion failed (vector iterators incompatible)

向量生成代碼:

instInFrustumData.reserve(mNumInstances); 

矢量更新代碼:

void Terrain::updateInstances() 
{ 
    mNumInstancesInFrustum = 0; 

    if(instInFrustumData.size() != 0) 
     instInFrustumData.clear(); 

    mpMxMInstInFrustumB->Map(D3D10_MAP_WRITE_DISCARD, NULL, (void**) &instInFrustumData); 

    for(int x = 0; x < mNumInstances; x++) 
    { 
     if(mpCamera->point2DInFrustum(instData[x].mTransform + 
      D3DXVECTOR2(instData[x].mSpacing/2 + mpCamera->getPosition().x, instData[x].mSpacing/2 + mpCamera->getPosition().z), instData[x].mSpacing/2) 
      != OUTSIDE) 
     { 
      instInFrustumData.push_back(instData[x]); 
      mNumInstancesInFrustum++; 
     } 
    } 

    mpMxMInstInFrustumB->Unmap(); 
} 

什麼能做到這一點?

而在我的類的析構函數我也呼籲猜測這裏的明確()

+1

您的發佈代碼不能 - 因此發佈更多。 – Erik 2011-04-28 18:20:02

+0

我發現另一件事:在創建矢量後,我調整它的大小以使其大小=容量。我打電話給clear()和它的ok,所以size = 0容量= 100,然後我只填寫8個值,當我再次打電話給clear時(第二次),錯誤被拋出 – 2011-04-28 18:21:56

+0

可能會發生這種情況的是可互換使用const和非const迭代器。然而,你需要發佈你的實際代碼,因爲你在這裏沒有造成這個錯誤。 – AJG85 2011-04-28 18:23:01

回答

2

你可能想看看使用std::vectorhttp://www.cplusplus.com/reference/stl/vector/的參考或購買一本好的STL書籍。你正在使用一些我認爲是非正統方法的方法。

  • 使用empty()來檢查,如果載體具有的元素(如果不是空的明確只是讀更好)
  • 使用局部範圍的變量時,可能(的事情,不需要留在範圍不應)
  • 使用STL迭代器或在循環容器大小(是有在需要一個迴路內遞增整數?)
  • 使用「最佳」 STL爲你實現集裝箱(做你想做的載體或者這裏的地圖?)
  • 避免C風格的演員和對象的誤用((void**) &instInFrustumData是一個非常糟糕的主意)

你有這麼多的成員變量,其定義是未知的,以及未知的方法Map()UnMap(),仍然沒有顯示出使用與原來的錯誤迭代器的任何代碼。我猜想你對instData[x]的使用是危險和有問題的,以及這個循環通常構造的方式。你也真的不想把STL容器當作STL容器來處理。應該避免像(void**) &instInFrustumData這樣的事情,因爲它們只會導致問題。

我強烈建議你先學習C++,然後再解決DirectX或者圖形和遊戲引擎。

+0

Map()和Unmap()方法是directX ID3D10Buffer方法(那就是爲什麼當我第一次寫這個問題時,我並沒有發佈完整的代碼,因爲我知道這會導致一些混淆),所以必須完成cast(void **)&instInFrustumData。 – 2011-04-28 19:13:37

+1

這很好。它似乎希望內存的一個輸出參數寫入以後可能用於繪圖。將STL向量的內部公開給沒有用STL設計的東西直接寫入是不是一個好主意。如果你**必須**,那麼我可能會使用'&instInFrustumData.data()',但老實說,我寧願在這種情況下使用一個字節數組,然後在我控制的代碼中填充我的向量。 – AJG85 2011-04-28 19:27:47

+1

我剛剛查找了方法...... Map()和Unmap()似乎是緩衝區的鎖定機制。可能最好使用更多沿着'boost :: mutex'和'boost :: mutex :: scoped_lock'或其他一些基於互斥鎖的鎖定的東西來控制對你的向量的寫訪問。如果不嘗試使用'&instInFrustumData.data()',因爲它實際上是指向分配向量內存的內部緩衝區的指針。 – AJG85 2011-04-28 19:44:19

2

類,但也許你的問題是這一行:

mpMxMInstInFrustumB->Map(D3D10_MAP_WRITE_DISCARD, NULL, (void**) &instInFrustumData); 

你傳遞一個指針向量本身到這個Map函數,我猜可能會覆蓋它的一些內部函數?我沒有它的文檔,但它看起來不像是一個指向矢量的函數:)

+0

我會嘗試找出它是否會導致錯誤:D – 2011-04-28 19:14:50