[sldev] [VIEWER] Daring construct? (is this safe?)
Q Linden
q at lindenlab.com
Wed Sep 26 09:45:55 PDT 2007
Caught me being lazy. It's not just associative containers -- lists
(because they're linked) don't invalidate on erase either, except for
iterators pointing to the element(s) being erased.
If you find any vectors or deques that use this idiom, that would be a
problem.
And sometimes, at least, an explicit iteration/erase is better solved
with remove_if, which works on all types of containers.
Q
Nicholaz Beresford wrote:
>
> A first quick (semi random) check brings up
>
> W:\sl1_18_3_5\linden\indra\newview\llselectmgr.cpp(5863):
> erase(mCurrentNode++);
>
> where mCurrentNode is an interator on a std::list.
>
>
> Nick
> ---
> Second Life from the inside out:
> http://nicholaz-beresford.blogspot.com/
>
>
> Q Linden wrote:
>> Yes, this is safe. The iterator post-increment returns a temporary
>> copy of the previous value, which is used for the erase (and
>> invalidated). The gi iterator is still valid in a map.
>>
>> If mGroups had been a vector or other non-hashed container instead of
>> a map, erasing an item invalidates ALL iterators and the code would
>> be unsafe.
>>
>> Q
>>
>> Nicholaz Beresford wrote:
>>>
>>> Seen in llgroupmgr.cpp at 1330
>>>
>>> mGroups is a std::map.
>>>
>>> Question is if the mGroups.erase(gi++); is safe or depends on
>>> order of evaluation and/or possibly accesses freed memory
>>> (doing the increment after the erase)?
>>>
>>> (I'm seeing this in a lot of places ... grep erase\(.*++\); ).
>>>
>>>
>>>
>>> // get rid of groups that aren't observed
>>> for (group_iter gi = mGroups.begin(); gi != mGroups.end() &&
>>> mGroups.size() > MAX_CACHED_GROUPS / 2; )
>>> {
>>> observer_iter oi = mObservers.find(gi->first);
>>> if (oi == mObservers.end())
>>> {
>>> // not observed
>>> LLGroupMgrGroupData* group_datap = gi->second;
>>> delete group_datap;
>>> mGroups.erase(gi++);
>>> }
>>> else
>>> {
>>> ++gi;
>>> }
>>> }
>>>
>>>
>>
More information about the SLDev
mailing list