good chemistry is complicated,
and a little bit messy -LW
Re^3: perlembed: mortalize an AV, get "Attempt to free unreferenced scalar" - don't mortalize, leaks memoryby demerphq (Chancellor)
|on Jul 10, 2006 at 13:53 UTC||Need Help??|
Update: Looks like this isnt right... Sigh
I thought my mortalized SVs were only supposed to be blown away when the following code gets executed:
Yes, the logic i explained is basically what happens when FREETMPS/LEAVE occurs. Dont take my description too literally, im far from being authority on the internals, just trying to add some insight based on the little understanding i do have.
So how could the values be freed too soon?
Im assuming the reason the vars could be blown away too soon is that when you mortalize a var it goes on a temps stack, which is then processed by the FREETMPS/LEAVE macros. If you mortalize a member element of a composite structure which is itself mortalized then presumably there will be two attempts to refcount-dec/free the same thing.
That leaks, but if I mortalize the SV as in the comment, everything is great, and there are no warnings. So what gives? What's the difference between the av_push and hv_store examples?
Im basically guessing, but id think the problem is that when you do newSVpv() the created SVPV has a refcount of 1. You then increment the refcount, bringing it to 2, (note that in the array example you do not do the additional SvREFCOUNT_inc()) then you hv_push into a mortalized hash, which is then referenced by a mortal SVRV. So the mortal SVPV gets its refcount decremented once by its own mortalization, and then decremented again when the hash is freed. If you dont mortalize the SVPV then its refcount is 1 and it leaks. However it seems to me that the proper thing to do here is to do something like:
The idea being that the only thing that needs to be mortal is the newRV(), which when its freed will cascade through the things it references, refcount decrementing them to 0 and thus causing them to be freed.
Anyway, its very possible ive gotten something horribly wrong, but this is more or less as i understand it.