Assertion given for erase() vector function

This piece of code is meant to erase an item of choice from a vector but for some reason every time it runs I get the assertion:

Expression:vector iterator + offset out of range


Not sure precisely what this means or how to fix it so if anyone can give me a hand I'd appreciate it.

1
2
3
4
5
cout << "\nPlease choose an item to remove: ";
			getline(cin, lineList);
			stream << lineList;
			stream >> listChoice;
			games.erase((games.begin() + (listChoice - 1)));
Last edited on
information you have given is not enough. i couldn't understand what you have posted
and why notlistChoice-=2?
does the system assertion mean you have give a iterator that beyond the range of vector game?
Well that's what I'm not sure of. It sounds like it's telling me that I'm out of range of the number of entries but the expression following games.erase(). The program asks for the user to input entries into the vector and can display the list and ask the user if they want to remove specific items from the list. I'm not using -=2 because that's actually a mistake, I forgot to remove that line after trying both out and I've edited the above but it makes no difference if I keep it as listchoice - 1 or not, it still displays the same assertion.

What more info is needed?
It really sounds like you are going out of range. Try checking the size() of the vector and the value of listChoice and see.
Well listChoice is 0 even if I change the expression games.erase((games.begin() + (listChoice - 1))); to + 4 instead of -1 (just trying a random number to see the result) and the vector size changes because the user has to put elements into the vector but it's always correct (i.e. if there's 9 elements it will display 9 when size() is output). I'll post the whole code if it will help at all but I'm not sure it will as this is the only part going wrong and it's fairly self contained. I'm just not sure how it's going out of range. The vector I used in my test held 10 elements and I tried to delete the 6th. The way I'm reading this code is that listChoice should = 6, therefore that expression should evalute to 5, or the 6th index in the vector. Am I mad or is something else happening that I'm just not seeing? It'll probably end up being something ridiculously simple but anyway, here's the full program:

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
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <sstream>

using namespace std;

stringstream stream;

int main()
{
	vector<string> games;
	vector<string>::iterator myIterator;
	string quit = "n";
	string gameChoice = "";
	int listChoice = 0;
	string lineList;

	while (quit != "y")
	{
		gameChoice = "";
		int choice;
		string lineChoice = "";
		stream.clear();

	cout << "\tWelcome to Game List.\n";
	cout << "\n1) Add to list\n";
	cout << "2) Remove From list\n";
	cout << "3) Display list\n";
	cout << "4) Quit program\n";
	
	cout << "\nChoice: ";
	getline(cin, lineChoice);
	stream << lineChoice;
	stream >> choice; 

	switch (choice)
	{
	case 1:
		{
			cout << "\nPlease type 'menu' when finished to return to the main menu.";
		while (gameChoice != "menu")
		{
			cout << "\nEnter a game to add to the list: ";
			getline(cin, gameChoice);
			games.insert(games.end(), gameChoice); //inserts entry into back of vector
			if (gameChoice == "menu")
				games.erase(games.end() - 1); //erases entry 'menu' if typed
		}
		break;
		}
	case 2:
		{
		while (gameChoice != "menu")
		{
			cout << "\nList:";
			int select = 0;
			for (myIterator = games.begin(); myIterator != games.end(); ++myIterator)
			{
				select++;
				cout << endl << select << ") " << *myIterator;
			}
			cout << "\nPlease choose an item to remove: ";
			getline(cin, lineList);
			stream << lineList;
			stream >> listChoice;
			games.erase((games.begin() + (listChoice -= 1))); //should erase chosen entry
		}
		break;
		}
	case 3:
		{
			if (gameChoice != "menu")
			{
				int select = 0;
				cout << "\nList:\n";
				for (myIterator = games.begin(); myIterator != games.end(); ++myIterator)
				{
					select++;
					cout << select << ") " << *myIterator << endl;
				}
			}
			break;
		}
	case 4:
		{
			cout << "\nWould you like to quit(y/n)? ";
			getline(cin, quit);
			cout << endl << endl;
			break;
		}
	default:
		cout << "\nPlease enter a valid selection.\n";
		break;
	}
	}

	if (quit == "y")
		cout << "\nThank you!\n\n";

	return 0;
}
The problem is with your conversion. I suppose when you do string to int conversion the second time it is affected be the first one. I was never very good with streams..
Anyway here's a function to fix it:
1
2
3
4
5
6
7
template<class T>
bool string_to_(T& res, string s){
    stringstream str;
    str << s;
    str >> res;
    return str.fail();
}


then replace each
1
2
stream << lineChoice;
stream >> choice; 

with
string_to_<int>(choice, lineChoice);

You may also want to handle the case when input cannot be converted to integer. (function returns 1)
Okay, I haven't moved onto streams and conversion as such yet so I'll implement this for now and learn all inner workings later but thanks! You've been extremely helpful so I thank you very much for giving me more to think about!
Topic archived. No new replies allowed.