Do erase call in std::set invalidate iterator ? As i have done below 5th from last line..? if yes what is better way to erase all elements from set
class classA
{
public:
classA(){};
~classA(){};
};
struct structB
{
};
typedef std::set <classA*, structB> SETTYPE;
typedef std::map <int, SETTYPE>MAPTYPE;
int __cdecl wmain (int argc, wchar_t* pArgs[])
{
MAPTYPE mapObj;
/*
...
.. Some Operation Here
...
*/
for (MAPTYPE::iterator itr1=mapObj.begin(); itr1!=mapObj.end(); itr1++)
{
SETTYPE li=(*itr1).second;
for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();itr2++)
{
classA *lt=(classA*)(*itr2);
li.erase(itr2);
delete lt; // Does it invalidate Iterator ?
}
}
}
The delete is ok.
The problem is that you erase - and thus invalidate -
itr2
, but use it for loop iteration.i.a.w. after the first erase, the
++itr2
has undefined results.The pattern I use in this situation is this:
Some non-standard STL impls have erase return the next iterator, so you could do:
that's not portable, though.
the
set<A*,B>
is strange, though - in a standard impl, B would be the comparator.From standard 23.1.2
EDIT
In your case itr2 is invalidated after erasing so incrementing it causes undefined behaviour. In this case you can follow reko_t advice, in general, you can try this:
which will increment iterator before removing it's previous value from set.
BTW. itr2 is not invalidated by
delete lt;
, but byli.erase(itr2);
Since you are just apparently deleting every element of the set, you could just do: