2011-04-28 112 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