Looping a list

Hello,

I am attempting to create a little program that iterates through a list deleting every third item until only one remains. Unfortunately, I feel as if I am going down a rabbit hole trying to fix my loop process. Good chance I am just thinking about it wrong.

Currently, I think I have two issues. First that my iterator needs to hold it's location after a node is erased, but mostly that once I we get to the end of the list we core dump... I can't seem to catch the iterator at the end.

Any help would be appreciated.

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
#include <iostream>
#include <list>

using namespace std;

void showRemains(std::list<int> &suit);

int main()   {

	int size;
	std::list<int> numb;
	std::list<int>::iterator it;
	

	std::cout << "Please input a number " << endl;
	

	while (!(std::cin >> size) || size < 0 )   {
		std::cout << "Please enter a valid number of number!" << std::endl;
		std::cin.clear();  // Clear cin stream
		std::cin.ignore(50, '\n');	// Ignore previous cin entries
	}
	
	std::cout << "Thank you. There are " << size << " numbers." << endl;
	
	for (int i=0; i<size; i++)  {
		numb.push_back(i+1);
		
	}
	

	showRemains(numb);
	
       it = numb.begin();

	while (numb.size() > 1)   {
		
		
		//std::cout << "size " << numb.size() << " it " << *it << endl;
		if (it == numb.end() ) { it = numb.begin(); }
		else { it++; }
		if (it == numb.end() ) { it = numb.begin(); }
		else { it++; }
		
		std::cout << "Number #" << *it << " removed." << endl;
		numb.erase(it);
		//std::cout << "size " << numb.size() << " it " << *it << endl;
		if (it == numb.end() ) { it = numb.begin(); }
		else { it++; }//advance to next 
		//std::cout << "size " << numb.size() << " it " << *it << endl;
		showRemains(numb);
		
	}
	
	std::cout << "Number #" << numb.front() << " is the final number!!!" << endl;
	
	
	
	

return 0;
}

void showRemains(std::list<int> &suit)  {

	std::cout << "Remaining numb" << endl;
	for (std::list<int>::iterator i=suit.begin(); i !=suit.end(); i++)   {
		std::cout << *i << " ";
	}
	std::cout << endl << endl;

return;
}


Edit: Well i figured out my first issue, I simply had set my iterator to begin() inside my while loop instead of before... I feel silly (updated the code accordingly). I am still getting a segmentation fault and am not sure why my if statements aren't bringing me back the the start.
Last edited on
1
2
3
4
numb.erase(it);
//std::cout << "size " << numb.size() << " it " << *it << endl;
if (it == numb.end() ) { it = numb.begin(); }
else { it++; }//advance to next  
You should never use invalidated iterators. In list iterators to deleted elements are invalidated. Save iterator to another variable, increment main iterator and delete saved one.
Thanks MiiNiPaa,

That makes sense, though I am not sure I understand the method which this can be done. If I create a second iterator equal to the one to be delete, would it too not be invalid after the delete?
You will use it only to delete and then won't touch it again.
If I understand correctly, it would be something like
1
2
3
		std::cout << "Number #" << *it << " removed." << endl;
		std::list<int>::iterator del = it;
		numb.erase(del);


But this seems to kill both it and del. So I am pretty sure I am not on the right track.
MiiNiPaa wrote:
Save iterator to another variable, increment main iterator and delete saved one.
1
2
3
std::list<int>::iterator del = it;
++it
numb.erase(del);
//or
std::list<int>::iterator del = it++;
numb.erase(del);
or..
numb.erase(it++);

or...
it = numb.erase(it);
Thanks again, reading comprehension is a good skill to have. Things are working much better now, though I have realized that referencing numb.end() is referring to "blank space" after the last element where I am attempting to compare to the last element.

		if (it == numb.end() ) { it = numb.begin(); }
		else { it++; }


Is there a trick to checking the end of the list? I attempted to use back() however I get invalid operators with that.

Got it!

By advancing the iterator, then checking for the end I am in the right spot when I check.

		it++; 
		if (it == numb.end() ) { it = numb.begin(); }


Thanks for the help everyone. This one is in the bag!
Topic archived. No new replies allowed.