0

I have this struct:

struct MxMInstanceData
{
    D3DXVECTOR2 mTransform;
    float mSpacing;
};

Then I create a vector of MxMInstanceData:

std::vector<MxMInstanceData> instInFrustumData;

If I call instInFrustumData.clear() I get this error:

Assertion failed (vector iterators incompatible)

Vector creation code:

instInFrustumData.reserve(mNumInstances);

Vector update code:

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

What can make this happen?

And in the destructor of my class I also call clear()

Tiago Costa
  • 4,151
  • 12
  • 36
  • 54
  • 1
    Your posted code can't - so post more. – Erik Apr 28 '11 at 18:20
  • I found another thing: After I create the vector I resize it so size = capacity. I call clear() and its ok, so size = 0 capacity = 100, then I only fill it with 8 values, and when I call clear again (for the second time) the error is thrown – Tiago Costa Apr 28 '11 at 18:21
  • Something that can make this happen is interchangeably using const and non-const iterators. However you need to post your actual code because what you have here is not causing this error. – AJG85 Apr 28 '11 at 18:23
  • Yes, that is also potentially unrelated so you should still simply post your actual code using the vector in complete form. Note however that you should use `reserve` to reserve a capacity in a vector without creating elements. `resize` will remove elements or expand the vector and potentially **create new empty elements** depending on the current size and elements present when calling it. – AJG85 Apr 28 '11 at 18:29
  • At first I used reserve, then I changed to resize but the error persisted... – Tiago Costa Apr 28 '11 at 18:33

2 Answers2

2

Kind of guessing here, but maybe your problem is this line:

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

You're passing a pointer to the vector itself to this Map function, which I'm guessing might be overwriting some of its internals? I don't have its documentation, but it doesn't look like a function that's expecting a pointer to a vector :)

Luke Halliwell
  • 7,312
  • 6
  • 31
  • 31
2

You may want to check out a reference on using std::vector like http://www.cplusplus.com/reference/stl/vector/ or buy a good STL book. You are using some methods in what I would consider unorthodox ways.

  • Use empty() to check if a vector has elements (if not empty clear just reads better)
  • Use locally scoped variables when possible (things that don't need to stay in scope shouldn't)
  • Use STL iterators or container sizes in loops (is having two incrementing integers in one loop needed?)
  • Use the "best" STL container for your implementation (do you want vectors or maps here?)
  • Avoid C-style casts and misuse of objects ((void**) &instInFrustumData is a very bad idea)

You have so many members variables whose definition is unknown as well unknown methods Map() and UnMap() and still haven't shown any code using iterators related to your original error. I would guess your use of instData[x] is dangerous and problematic as well as the way that loop is constructed in general. You also really don't want to be treating STL containers as anything but STL containers. Things like (void**) &instInFrustumData should be avoided as they can only cause problems.

I highly suggest you learn C++ first before tackling DirectX or graphics and game engines written in both.

AJG85
  • 15,849
  • 13
  • 42
  • 50
  • Map() and Unmap() methods are directX ID3D10Buffer methods (thats why I didnt posted the full code when I first wrote this question, because I knew it would cause some confusion), so the cast (void**) &instInFrustumData must be done. – Tiago Costa Apr 28 '11 at 19:13
  • 1
    That's fine. It appears to want an out parameter of memory to write to possibly for drawing later. It's not a great idea to expose the internals of a STL vector to be written to directly by something not designed with STL in mind. If you **MUST** then I would probably use `&instInFrustumData.data()` but honestly I would prefer to use a byte array in this case then populate my vector in code I control. – AJG85 Apr 28 '11 at 19:27
  • 1
    I just looked up the method ... `Map()` and `Unmap()` appear to be locking mechanisms for the buffer. It might be preferable to use something more along the lines of `boost::mutex` and `boost::mutex::scoped_lock` or some other mutex based locking for controlling write access to your vector. If not try using `&instInFrustumData.data()` instead as that is actually a pointer the internal buffer where the vector's memory is allocated. – AJG85 Apr 28 '11 at 19:44
  • instInFrustumData.data() fixed it, so many thanks :D. Can you tell me the name of a good STL book because I only know the basics of STL... I didnt even knew the existence of data() method... Also I'm not familiar with boost namespace. I will also buy a book about more advanced C++ because the one I have is really basic so I dont even know what are templates etc :S – Tiago Costa Apr 28 '11 at 19:58
  • 1
    http://www.boost.org/ is a pretty stellar 3rd party C++ library so good in fact that much of it is being adopted into the new C++ standard and is partially available in new form under the `std::tr1` namespace. As far as books I'd recommend anything by Scott Meyers or Herb Sutter for some really good tips and tricks but check out this article for reference: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – AJG85 Apr 29 '11 at 20:24