map /set iterator not incrementable

hello,

i have this code. when i run it i get a runtime error: map /set iterator not incrementable on line 209. I am not sure why but when i check it2 under watchlist when it crashes it already points at "end".

I can't think of why that happens, because i have defined it2 as a local variable.

argv[1] is just a txt file with some random numbers in it.


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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
  #include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <locale>
# include <algorithm>
# include <regex>
# include <list>
#include <map>
#include <set>


using namespace std;


template <typename T>

void print(T& c)
{
	cout << "Here is the dataset: ";

	for (auto x : c)
	{
		cout << x << " ";
	}


	cout << endl;

}



template <typename T>
void printmap(T& c)
{
	cout << "here is the map\n";

	for (auto p : c)
	{
		cout << p.first << "  " << p.second << endl;
	}

	cout << endl;


}




int main(int argc, char* argv[])
{
	//1. Read in the filename and open an input filestream
	ifstream inFile(argv[1]);
	//Test for success
	if (!inFile)
	{
		cerr << "Input file opening failed.\n";
		return EXIT_FAILURE;
	}

	//2. Get the numbers  from the file and store in a vector

	vector<int> v;
	string word;
	while (getline(inFile, word))
	{
		// convert string word to a number 
		int number = stoi(word);

		v.push_back(number);

	}


	//Finished reading in file
	cout << "Finished reading in file!\n";

	inFile.close();

	list<int> l;

	l.insert(l.end(), v.begin(), v.end()); 


	/*
	cout << "\nThe list with vector elements added to the end:\n";
	for (auto p : l)
		cout << p << " ";
	cout << endl;
	*/

	print(l);




	set<int> set2(v.begin(), v.end());

	print(set2); 


	map< int, int> mFrequency;

	for (unsigned i = 0; i < v.size(); ++i)
	{
		//mFrequency[v[i]] =  10 ;

		//mFrequency[v[i]] += 1; 

		++mFrequency[v[i]];


	}


	cout << "print map mFrequency using function " << endl; 

	printmap(mFrequency);

	// print each container using iterators


	cout << "print each key and value using iterator " << endl; 
	
	for (map<int, int >::iterator it = mFrequency.begin(); it != mFrequency.end(); ++it)
	{
		cout << " mFrequency[i] = key " << (*it).first << "value" << (*it).second << endl;

		//cout << " mFrequency[i] = key " << it->first << "value" << it->second << endl;

	}



	int largest = 0; 

	for (map<int, int >::iterator it = mFrequency.begin(); it != mFrequency.end(); ++it)
	{
		//cout << " mFrequency[i] = key " << (*it).first << "value" << (*it).second << endl;

		if ((*it).second > largest)
		{

			largest = (*it).second; 

		}

		//cout << " mFrequency[i] = key " << it->first << "value" << it->second << endl;

	}

	cout << "times the most frequent number/s occurs is " << largest << endl;


	for (map<int, int >::iterator it = mFrequency.begin(); it != mFrequency.end(); ++it)
	{
		//cout << " mFrequency[i] = key " << (*it).first << "value" << (*it).second << endl;

		if ((*it).second == largest)
		{

			cout << "mode is " << (*it).first << " ";

		}

		//cout << " mFrequency[i] = key " << it->first << "value" << it->second << endl;

	}



	int cunique = 0; 

	for (map<int, int >::iterator it = mFrequency.begin(); it != mFrequency.end(); ++it)
	{
		//cout << " mFrequency[i] = key " << (*it).first << "value" << (*it).second << endl;

		if ((*it).second == 1)
		{

			++cunique; 

		}

		//cout << " mFrequency[i] = key " << it->first << "value" << it->second << endl;

	}

	cout << "number of unique numbers  is  " << cunique << endl; 




	int total = 0; 

	for (map<int, int >::iterator it = mFrequency.begin(); it != mFrequency.end(); ++it)
	{
		
	 ++total;

	}

	cout << "total number before removing odd numbers" << total << endl; 
	
	// erasing odd elements from the map 

	for (map<int, int>::iterator it2 = mFrequency.begin(); it2 != mFrequency.end(); ++it2)
	{
		// if the number is odd 
		if ((*it2).first % 2 == 1)
		{

			mFrequency.erase(it2); 
		}

	}

	cout << "map after erasing odd elments" << endl; 

	printmap(mFrequency); 


	int ceven = 0; 

	for (map<int, int >::iterator it = mFrequency.begin(); it != mFrequency.end(); ++it)
	{
		
		

		++ceven;
		

	}


	cout << "total number of elements after removing odd elements is  " << ceven << endl;






	for (list<int>::iterator it = l.begin(); it != l.end(); ++it)
	{ 

		cout << *it << " ";


	}

	cout << endl;


	//set<int>::iterator it

	for (set<int>::iterator it = set2.begin(); it != set2.end(); ++it)
		cout << *it << " ";

	cout << endl; 

	cout << "print set using reverse iterators" << endl;

	set<int>::reverse_iterator rit;

	for (rit = set2.rbegin(); rit != set2.rend(); ++rit)
		cout << *rit << " ";

	cout << endl;



	system("pause");

}
Last edited on
Hello masterinex,

Include an example of your input file. It makes it easier to run your program.

Andy
The iterator gets invalidated when you remove the element so you need to assign a valid iterator value to it before using it again. You can use the return value of the erase function which is an iterator to the element after the erased element.

 
it2 = mFrequency.erase(it2);


You also need to avoid incrementing the iterator after an element has been erased because otherwise the loop will skip elements that comes after an erased element. You can do that by moving the iterator increment inside an else part of the if statement.

1
2
3
4
5
6
7
8
9
10
11
12
for (map<int, int>::iterator it2 = mFrequency.begin(); it2 != mFrequency.end();)
{
	// if the number is odd 
	if ((*it2).first % 2 == 1)
	{
		it2 = mFrequency.erase(it2); 
	}
	else
	{
		++it2;
	}
}
thanks Peter,

here is the input file :

4
21
28
17
14
10
27
10
16
23
21
17
25
11
12
9
28
4
4
4
4
4
4
4
4
9
9
99
99
99
99
99
99
99
99
99
99
99
9
9
9
9
9
9
4
18
9
4
9
21
30
27
12
13
12
13
218
273
97
254
344
240
132
363
72
326
48
315
152
268
432
188
61
141
Topic archived. No new replies allowed.