[perl #85026] deleting elements in a HASH iterator
authorTon Hospel <me-02@ton.iguana.be>
Mon, 16 May 2011 15:33:07 +0000 (08:33 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 20 May 2011 00:09:46 +0000 (17:09 -0700)
commitae19993915a27e9fb5ee79b7a2624dba0bd876cd
tree3d471cddcbb95cc0b57649a01d89ad8aa84c4cfc
parent57f6eff5f803b7abef8aa97b0d7609a181b9b4d7
[perl #85026] deleting elements in a HASH iterator

Internally a perl HASH is an array of single linked chains of entries.
Deleting an element means removing the correct chain entry by replacing
the pointer to the removed entry with a pointer to the next entry and
then freeing the deleted entry

However, if the deleted element is the current entry the deleted entry
is kept after removing it from the chain and the LAZYDEL flag is set.
Only on the next iteration is the element actually removed and the
iterator is set to the next entry.

However, if you delete the current iterator and then delete the next
element in the same chain the "next" pointer of the iterator is not
updated because the iterator is not on the chain anymore. That means
that when the next iteration looks up the iterator next pointer it
will point to the freed memory of the second element.

This patch fixes the places where the delete is done. Drawback is that
you may never forget to do the lazydel fixup in at any place where the
entry chain gets shortened.
hv.c