in reply to
Re^5: perlembed: mortalize an AV or not (misc)
in thread perlembed: mortalize an AV, get "Attempt to free unreferenced scalar" - don't mortalize, leaks memory
Thanks tye - this is extremely helpful. So I just want to make sure that I understood properly what you recommend to do. Does the following code give a decent example of how to push an array ref and a hash ref onto the stack?
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
AV *arr = newAV();
av_push( arr, newSVpv("string", 0));
XPUSHs(sv_2mortal(newRV_noinc((SV *)arr)));
HV *hash = newHV();
SV *type = newSVpv("string", 0);
hv_store( hash, "type", strlen("type"), type, 0);
XPUSHs(sv_2mortal(newRV_noinc((SV *)hash)));
PUTBACK;
call_sv(sv_2mortal(newSVpv("TestPM::test_leak", 0)), G_SCALAR);
SPAGAIN;
SV *retval = POPs;
PUTBACK;
FREETMPS;
LEAVE;
I'd really appreciate it if you could validate this approach, which is my understanding of what you explained above.
Regarding your other questions:
- The printf/exit was just an example - my real code is actually throwing an exception there. Actually, it's also doing a FREETMPS/LEAVE - is that the right thing to do if I'm expecting the process to stay alive, and I want everything cleaned up? Will that work okay with the non-mortal approach you're advocating?
- I was calling SvREFCNT_inc() since it seemed to me from the hv_store() docs that I needed to. But you're saying that I don't, right? I have to say that I'm still left feeling like the above code might work, but isn't really handling refcounts correctly. But I trust you more than I trust my gut feelings here...
- call_sv() was also just an example - my real code is calling call_method().
So wouldn't it be better if I do mortalize everything, and just SvREFCNT_inc whenever I either av_push() or hv_store() the SV, as well as using newRV_inc()? Will that not work and be correct?