Why does my iterator go out of bounds?

I'm trying to write a simple directory program. I have a class called Entry, which is stored in a vector<Item> directory. I can add and search entries, but I'm having trouble deleting an entry.

The function for deleting an item is below. I get a Debug Assertion Failed Error ("Expression: vector iterator not dereferencable") when the dir.erase line is reached.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 void deleteEntry(std::vector<Entry>& dir, std::string query)
{
	std::vector<Entry>::iterator it = dir.begin();
	query = convertUp(query);

	while (it != dir.end())
	{
		if ((query == it->m_getName()) || (query == it->m_getEmail()))
		{
			std::vector<Entry>::iterator temp = it++;
			dir.erase(temp);
			std::cout << "Entry for " << it->m_getName() << " deleted" << std::endl;

		}

		else ++it;
	}
}


Originally I did not have a temp iterator, it was a simple for loop with the erase line reading:

dir.erase(it)

I read that erasing objects in the middle of a vector can cause problems, though I'm not 100% clear what those problems are. Is this what is happening here? I have a feeling the iterator is being pushed out of bounds, but I can't see where that is happening. Maybe the erase syntax is wrong. Could anybody help?
Last edited on
vector::erase invalidates iterators but returns a valid iterator so...it = dir.erase(temp);
Thanks naraku, I didn't realise erase returns an iterator. That makes a certain amount of sense, but I still can't get my function working. I'm using this piece of code as reference, when a similar question was asked:

1
2
3
4
5
6
7
for( ; it != res.end();)
{
    if (smth)
        it = res.erase(it);
    else
        ++it;
}


I've simplified my own code further, it seems to match the above, but I still get the same error.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void deleteEntry(std::vector<Entry>& dir, std::string query)
{
	std::vector<Entry>::iterator it = dir.begin();

	while (it != dir.end())
	{
		if (query == it->m_getName() || query == it->m_getEmail())
		{
			it = dir.erase(it);
			std::cout << "Entry for " << it->m_getName() << " deleted" << std::endl;
		}

		else ++it;
	}
}
Last edited on
Ack, I found the problem...it was in the cout message, which was still referencing a deleted object. At least that's how I understand it.

Placing that before the erase fixed it.

Thanks for setting me in the right direction anyway.
Topic archived. No new replies allowed.