does STL hash_multiset erase invalidate the iterator?

K

Kenneth Massey

Is the following code guaranteed to work? I have a hashed set of pointers,
which I would like to selectively delete from. Can I iterate through the
set, deleting certain ones, without invalidating the iterator? This
ominous statement in the STL "set" documentation makes me worried. I saw
no similar statement on the "hash_multiset" docs.

"Erasing an element from a set also does not invalidate any iterators,
except, of course, for iterators that actually point to the element that is
being erased."



hash_multiset<mytype*> myset;
// insert a bunch of mytype pointers into myset

for (hash_multiset<mytype*>::iterator i=myset.begin(); i!=myset.end(); i++)
if (mytype->someproperty() == 1) {
mytype* p = *i;
myset.erase(i);
delete p;
}


Thanks.
 
J

John Harrison

Kenneth Massey said:
Is the following code guaranteed to work? I have a hashed set of pointers,
which I would like to selectively delete from. Can I iterate through the
set, deleting certain ones, without invalidating the iterator? This
ominous statement in the STL "set" documentation makes me worried. I saw
no similar statement on the "hash_multiset" docs.

"Erasing an element from a set also does not invalidate any iterators,
except, of course, for iterators that actually point to the element that is
being erased."



hash_multiset<mytype*> myset;
// insert a bunch of mytype pointers into myset

for (hash_multiset<mytype*>::iterator i=myset.begin(); i!=myset.end(); i++)
if (mytype->someproperty() == 1) {
mytype* p = *i;
myset.erase(i);
delete p;
}

Well you ARE invalidating the iterator, because it does point to the element
being erased. You erase i and then you do i++, that is using an invalidated
iterator.

Here's how to do it

hash_multiset<mytype*>::iterator i=myset.begin();
while (i!=myset.end())
{
if (mytype->someproperty() == 1)
{
mytype* p = *i;
myset.erase(i++);
delete p;
}
else
{
++i;
}
}

By saying 'myset.erase(i++);' you make sure that the iterator is incremented
before you erase not afterwards.

john
 
K

Kenneth Massey

John said:
Incidentally there is no need for the variable p.

delete *i;
myset.erase(i++);

john

Thanks for the help.
Actually I want to make sure the pointer is deleted *after* the set entry
has been erased. My hash and equal functions reference the pointer through
->, and I don't want to risk them being called on a deleted pointer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top