in reply to Re^3: Use of freed value in iteration
in thread Use of freed value in iteration

Yes, that is the point. The warning "Use of freed value in iteration" is great for catching bugs, but it can easily fail to catch one if the memory location of the deleted item is replaced with something else. If that something else happens to be the same type as the original item, then it could be a really insidious bug.
"but if you change the loop to iterate over @values or the keys of $hr3 then the issue disappears"

Yeah, iterating over @values would be really bad if you wanted to ensure you are only dealing with things defined in $hr3. Iterating over the keys of %$hr3 is definitely the safer way to go. That way when $hr3->{$key} is accessed you'll get a warning if it doesn't exist.

Replies are listed 'Best First'.
Re^5: Use of freed value in iteration
by swl (Prior) on Feb 12, 2024 at 23:30 UTC

    I wonder if this is an example of the stack not being ref-counted. Hopefully someone is able to test with a recent 5.39 perl with the ref-counted stack enabled.

    (Edited grammar after posting).

      > I wonder if this is an example of the stack not being ref-counted

      I discussed it with Pali and he thinks it is a refcounting problem. It seems when iterating over values, the refcount of the current element is incremented, but all other elements keep their refcounts unchanged. Therefore, iterating over something doesn't prevent non-current elements from destruction. To see what happens,

      use Devel::Peek;
      and prepend
      Dump $hr3;
      to the beginning of the loop.

      For loop is implemented by a stack: pp_hot.c and pp_ctl.c.

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        "It seems when iterating over values, the refcount of the current element is incremented, but all other elements keep their refcounts unchanged. Therefore, iterating over something doesn't prevent non-current elements from destruction."
        That seems like a good feature instead of a problem. If an element disappears I want to know about it. If I don't care if it disappears I can make copies of the elements beforehand. To me the problem seems to be that the deleted element can erroneously reappear as something else if it's memory location is reused. For hashes this can be avoided by iterating over keys and checking if the key still exists when it is to be used.