Can remove AA elements during foreach?

Nick Sabalausky SeeWebsiteToContactMe at semitwist.com
Sat Feb 16 17:04:28 PST 2013


On Sat, 16 Feb 2013 16:20:30 -0800
"H. S. Teoh" <hsteoh at quickfur.ath.cx> wrote:

> 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);
> 

Yea, that's the fallback I was using. Not that it's critical, but I was
hoping there'd be a simple way to do it without a dynamic allocation.



More information about the Digitalmars-d-learn mailing list