Reputation: 2801
Here's my precious little piece of code that makes my VC++ 2012 shiver, whereas if I run the same code on a Mac, there seems to be no problem at all.
for(auto trace : _traces) {
std::list<tuio::Cursor> cursors = trace.second.cursors;
std::vector<Vec2f> v;
for(tuio::Cursor p : cursors) {
v.push_back(p.getPos());
}
if(v.size() > 2) {
BSpline2f l(v, min((int)v.size()-1, 3), false, true);
PolyLine2f pl;
for(int i = 0; i < v.size(); i++) {
float t = (float)i/(float)v.size();
pl.push_back((l.getPosition(t)*s)+o);
}
gl::draw(pl);
}
tuio::Cursor c = cursors.back();
gl::drawSolidCircle((c.getPos()*s)+o , _scale * 10.0f);
}
at this point it would make sense to let you know that _traces
is a std::map<int, TouchTrace>
and TouchTrace
is a class I defined, which is basically a container for a list of tuio::Cursor
plus some additional awesomeness. I figure it matters quite little for this questions, especially since the members are public and I directly deal with them, so you can effectively see all my dirty laundry here in this snippet.
The trouble is that I randomly get a "map/set iterator not incrementable" exception, especially when I go a bit crazy and draw a very long trace (but fecal matter happens sometimes for shorter traces, that's the problem with random things). Plus, it only happens when I lift my finger off the tabletop (you get the idea) at which I perform this nifty little piece of code here:
void TheApp::cursorRemoved(tuio::Cursor cursor) {
_traces[cursor.getSessionId()].addCursorUp(cursor);
_traces.erase(cursor.getSessionId());
// Well, that was abrupt.
}
Note the comment, in case you need to smack me with a hard stick if the problem turns out to be some weird kind of cross-run between this main thread and the drawing thread. At this point it would probably matter, or not, to let you know I'm using libCinder, although I know very little about its internals so I can only speculate that the application and the drawing run in different threads. Anyways.
The backtrace identifies that for
on the first line, and of course the exception is thrown by std::_Tree_const_iterator<something>
, about which I suspect I should know nothing, Jon Snow. The auto
thingie seems to work properly, or at least that's what VS tells me, so I figured something was wrong with the foreach
construct and rewrote it with explicit iterators and the like.
How wrong I was. Next, I changed the auto into their explicit types, but nothing got better. Well, not really, since at some point I got a different exception, something about list iterators not being compatible, which is why I threw the autos away and hard-coded the actual types.
Although at this point I'm effectively employing plain old C++03 techniques, the rest of the code is still being compiled as C++11 by VS 2012, which is not exactly known to be reliable when dealing with cutting edge technology (as a matter of fact, the last time I checked, which is just more than six months ago, it didn't even support range-based for loops).
Any idea appreciated.
Upvotes: 0
Views: 387
Reputation: 3660
If you erase a cursor from _traces
while being in the loop for(auto trace : _traces) {
, the loop iterator gets invalidated
Upvotes: 3