Archived

This topic is now archived and is closed to further replies.

hash_map trouble

This topic is 5311 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having trouble erasing a certain element in a hash_map based on data retrieved from the element. I get access violations!
/*
	$name: clean()
	$desc: Cleans every resource entry with 0 ref count
*/
void NmdResourceManager::clean()
{
	hash_map<_TCHAR *, NmdResourceEntry *>::iterator hmIterator;

	if (_hmResourceList.empty())
		return;

	for (hmIterator = _hmResourceList.begin(); hmIterator != _hmResourceList.end(); hmIterator++)
	{       // ACCESS VIOLATION READING THE REF COUNT!

		if (hmIterator->second->getReferenceCount() == 0)
			_hmResourceList.erase(hmIterator);
	}
}
I'm implementing a clean function in my resource manager that erases from the list those elements which reference count is zero. The thing is, if I just do the iterator->element->getReferenceCount part everything's ok. The moment I add the list->erase part, things get messy. Why is this? It's not the erase function that screws, or is it? In that case this error is crap. Thanks [edited by - Deadman55 on June 4, 2003 3:27:45 AM]

Share this post


Link to post
Share on other sites
I''m willing to bet that the erase call is invalidating the iterator. This is one of those classic container erasing cases then.

I can''t remember off the top of my head, but if you need to erase the iterator, then don''t increment it. In that case, either the erase method sets the iterator to the next element or it returns an iterator to that element, I can''t rememeber

Share this post


Link to post
Share on other sites
Okey I realized I erase the desired elements correctly, but then the iterator points, after another increment, to an unvalid object in the list (end of the list?) and naturally, the element becomes unreadable.. Is there a way to verify the element pointed to by the iterator?
Except for

if iterator != list.end()

or

if iterator->second != NULL

because those statements always seem to be true..

Share this post


Link to post
Share on other sites
Yeah, the erase call invalidates the iterator, because what it used to point to no longer exists.

Erasing elements from a container in a loop like this is always tricky, because of iterator invalidation. I think something like this is it (simplified):

for(it = begin(); it != end(); )
{
if(condition)
{
it = container.erase(it);
}
else
{
++it;
}
}

Or at least very similar. I''m not clear about the hash_map erase function definition, if it returns a value or is passed by reference, etc. You''ll to experiment. You can also try searching the forum, this problem has come up several times before.

Share this post


Link to post
Share on other sites