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

The code is modifying the hash while iterating over its values and using those values as the keys for deletion. You perhaps already tried this, but if you change the loop to iterate over @values or the keys of $hr3 then the issue disappears. Same if you stringify the loop iterator $v.

Others can better comment on the details, but I assume perl is re-using memory and your code is reaching into the old locations.

Replies are listed 'Best First'.
Re^4: Use of freed value in iteration
by Danny (Chaplain) on Feb 12, 2024 at 23:02 UTC
    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.

      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]