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