Reputation: 32755
I'm trying to walk through a list. Here are some declarations:
list<CG1_Edge*> ActiveEdges;
list<CG1_Edge*>::iterator ActiveEdgeIterator;
Sometimes, this code segfaults on line 2:
for (this->ActiveEdgeIterator = this->ActiveEdges.begin(); this->ActiveEdgeIterator != this->ActiveEdges.end(); ++this->ActiveEdgeIterator) {
CG1_Edge* currentEdge = *this->ActiveEdgeIterator;
if (currentEdge->y_up < y)
this->ActiveEdges.erase(this->ActiveEdgeIterator);
}
Are there any common reasons why this might result in a segfault?
Upvotes: 3
Views: 1181
Reputation: 392921
Begemoth's comment should be the accepted answer. According to the standard erase invalidates "all iterator and references to elements after position"(my mistake; this was for vector and possibly other containers; so at least to avoid surprises you should do well to use the algorithm version instead).
So you'd be safer already using rbegin() and rend(). But why not use the std::alogirthms!
struct Predicate
{
int _y;
explicit Predicate(int y) : _y(y) {}
bool operator()(const CG1_Edge edge) const
{
return currentEdge->y_up < _y;
}
};
std::erase(
std::remove_if(this->ActiveEdges.begin(), this->ActiveEdges.end(), Predicate(y)),
this->ActiveEdges.end());
Upvotes: 0
Reputation: 206689
You should use something like:
for (this->ActiveEdgeIterator = this->ActiveEdges.begin(); this->ActiveEdgeIterator != this->ActiveEdges.end(); ) {
CG1_Edge* currentEdge = *this->ActiveEdgeIterator;
if (currentEdge->y_up < y)
this->ActiveEdgeIterator = this->ActiveEdges.erase(this->ActiveEdgeIterator);
else
++this->ActiveEdgeIterator;
}
since erase returns an iterator positionned at the next element.
(Note: having that iterator as a member looks strange.)
Upvotes: 5