in reply to Use of freed value
You might have checked perldiag, which leads with "Perhaps you modified the iterated array within the loop?" But that's not the case. As the question mark suggests, it's giving you the common case that results in this error, but it's not describing the real problem.
Perl uses reference counting as its garbage collection mechanism. For every place a scalar is referenced, its reference counter is incremented. When something stops referencing a scalar, its reference counter is decremented. If the reference counter reaches zero, the value is destroyed and freed.
Well, there's an exception to that: When placing a value on the stack, it's reference count isn't incremented. I don't know why, but that's the way it is.
This means that returning values that you no longer reference is tricky. Any XS programmer knows that if you want to return a scalar that you no longer reference, you make it a mortal rather than decrementing its reference count (which would free it prematurely). Making a scalar mortal adds it to a list of scalars to free in the caller once the caller has had a chance to take ownership of the scalar by incrementing its reference count.
This also means that the elements of @a in my code are freed (by @a=()) while they are on the stack waiting for the loop to start (first snippet) or to be assigned to @b (second snippet).
This is just two of many bugs caused by reference counting not applying to the stack. Fun!
|
|---|