On Sun, Nov 28, 2004 at 02:24:28PM +0100 Tels wrote: > I have seen some alarming memory growth on an application of mine, and have > the hunch that Math::BigInt::GMP is leaking memory. The included test script > outputs:
[...] > void > _sub(Class,x,y, ...) > SV* x > SV* y > PREINIT: > mpz_t* TEMP; > mpz_t* TEMP_1; > mpz_t* TEMP_2; > PPCODE: > GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ > if ( items == 4 && SvTRUE(ST(3)) ) > { > /* return new(y - x) */ > /* need to create TEMP_2 or it will ssegfault */ > TEMP_2 = malloc (sizeof(mpz_t)); mpz_init(*TEMP_2); > > mpz_sub(*TEMP_2, *TEMP, *TEMP_1); > > PUSHs(sv_setref_pv(sv_newmortal(), "Math::BigInt::GMP", (void*)TEMP_2)); > /*PUSHs(sv_setref_pv(y, "Math::BigInt::GMP", (void*)TEMP_2)); */ The problem is this line (any of the two). sv_setref_pv() returns a new SV which you need to mortalize: PUSHs(sv_2mortal(sv_setref_pv(y, "Math::BigInt::GMP", (void*)TEMP_2)); I find this fact slightly unintuitiv as I wouldn't expect a sv_set* function to create a new SV. However, the source clearly says: SV* Perl_sv_setref_pv(pTHX_ SV *rv, const char *classname, void *pv) { ... sv_setiv(newSVrv(rv,classname), PTR2IV(pv)); return rv; } This is actually a good reason to use a typemap on return values and assign TEMP2 to RETVAL. The C-code generated by xsubpp mortalizes the wrapper SV for RETVAL. Maybe this is one reason why I wasn't really aware that sv_setref_pv needs mortalizing since I always use it through a typemap. Other than that, you shouldn't be using malloc or any of the other memory allocators of the libc directly. The perlapi defines wrappers for them: New/Newz/Renew and Safefree for freeing thusly allocated memory. See perlclib.pod for details. Tassilo -- $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({ pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#; $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval