Vector iterator not incrementable?

Hi all,

I'm getting this error: "Expression: vector iterator not incrementable" at run time with the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
bool Digraph::removeVertex(const string& toRemove) {
	int labelIndex = findLabel(toRemove);

	if( labelIndex != -1 ) { // CASE: toRemove is in the set
		
		for(auto it = verLabels.begin(); it != verLabels.end(); it++) { // Loop verLabels
			if(*it == toRemove) { // CASE: toRemove is found
				verLabels.erase(it);
				nVertices--;
			} // END if
		} // END for

		for(auto it = adjLists.begin(); it != adjLists.end(); it++) { // Loop lists
			if( (*it).front() == toRemove ) { // CASE: toRemove is found
				nEdges -= (*it).size();

				adjLists.erase(it);
			} // END if
		} // END for(it)

		for( int i = 0; i < adjLists.size(); i++ ) { // Loop adjLists
			for( auto listIt = adjLists[i].begin(); listIt != adjLists[i].end(); listIt++ ) { // Loop list elements
				if( *listIt == toRemove ) { // CASE: toRemove found
					adjLists[i].erase(listIt);
					nEdges--;
				} // END if
			} // END for(listIt)
		} // END for(i)

	return true;
	} // END if

return false;
} // END removeVertex(const string& toRemove) 


I'm pretty certain that vector iterators are incrementable, especially after looking on the <vector> page and seeing .begin() returns a random access iterator. Am I getting the error because of my use of auto considering verLabels is type vector<string> and adjLists is vector< list<string> >?
Last edited on
You are making the classic mistake of deleting items from a sequence in a loop without ensuring your iterator remains valid.

google erase-remove idiom.
I think I understand: after erasing the element pointed to by an iterator the iterator becomes invalid and can't be incremented, right?

Would an offset iterator solve this?
EX:
1
2
3
4
5
6
7
8
9
10
11
12
13
auto prev = container.begin();
for(auto it = container.begin(); it != container.end(); it++) {
         if(*it == toFind) {
                  container.erase(it);
                  if(it == container.begin()) {
                       it = container.begin();
                       prev = container.begin(); // EDIT: Oops! Forgot to reset this iterator
                  } else {
                       it = prev;
                  }
         }
         prev++;
}


I saw the std::remove function but want to make sure I understand what's going on and how to fix it (at least naively) before I use it.

Thank you very much!
Last edited on
Update: Got it! Added some if/else's to handle when an iterator became invalid (was erased)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
bool Digraph::removeVertex(const string& toRemove) {
	int labelIndex = findLabel(toRemove);

	if( labelIndex != -1 ) { // CASE: toRemove is in the set
		
		for(auto it = verLabels.begin(); it != verLabels.end(); it++) { // Loop verLabels
			if(*it == toRemove) { // CASE: toRemove is found
				if(it == verLabels.begin() ) {
					verLabels.erase(it);
					it = verLabels.begin();
				} else {
					auto temp = it - 1;
					verLabels.erase(it);
					it = temp;
				}
				nVertices--;
			} // END if
		} // END for

		for(auto it = adjLists.begin(); it != adjLists.end(); it++) { // Loop lists
			if( (*it).front() == toRemove ) { // CASE: toRemove is found
				nEdges -= (*it).size();
				if(it == adjLists.begin() ) {
					adjLists.erase(it);
					it = adjLists.begin();
				} else {
					auto temp = it - 1;
					adjLists.erase(it);
					it = temp;
				}
			} // END if
		} // END for(it)

		for( int i = 0; i < adjLists.size(); i++ ) { // Loop adjLists
			for( auto listIt = adjLists[i].begin(); listIt != adjLists[i].end(); listIt++ ) { // Loop list elements
				if( *listIt == toRemove ) { // CASE: toRemove found
					if(listIt == adjLists[i].begin() ) {
						adjLists[i].erase(listIt);
						listIt = adjLists[i].begin();
					} else {
						auto temp = listIt--;
						listIt = temp;
					}
					nEdges--;
				} // END if
			} // END for(listIt)
		} // END for(i)

	return true;
	} // END if

return false;
} // END removeVertex(const string& toRemove) 
1
2
3
4
5
6
7
auto it = container.begin();
while ( it != container.end() ) {
         if(*it == toFind)
                  it = container.erase(it);
         else
                  ++it;
}
Topic archived. No new replies allowed.