Can remove AA elements during foreach?

H. S. Teoh hsteoh at quickfur.ath.cx
Sat Feb 16 16:20:30 PST 2013


On Sat, Feb 16, 2013 at 06:59:59PM -0500, Nick Sabalausky wrote:
> Is this both legal and safe?:
> 
>     foreach(key; assocArray)
>     if(key != "foobar")
>         assocArray.remove("foobar");
> 
> If not, then what about this?:
> 
>     foreach(key; assocArray.byKey())
>     if(key != "foobar")
>         assocArray.remove("foobar");

Both are unsafe, because opApply, byKey, byValue, rely on a pointer to
the current AA Slot and a pointer to the hash table to keep track of
where they are. Modifying the AA while in the middle of doing this may
cause strange effects, like the loop terminating prematurely, or
traversing already-deleted items. Keep in mind that a rehash may occur
during modification, so imagine what it will do if you're still
iterating pointers to the original AA.

For full fool-proofness, do this:

	auto keys = assocArray.keys;
	foreach (key; keys)
		doWhateverYouWantHere(key);


T

-- 
The fact that anyone still uses AOL shows that even the presence of
options doesn't stop some people from picking the pessimal one. - Mike
Ellis


More information about the Digitalmars-d-learn mailing list