Hi, I'm using the XS stack macros to call a method that returns a reference to an array. The way I think I should do it performs correctly but emits spurious warnings of "Attempt to free unreferenced scalar..." When I try to eliminate that message by toying with reference counts and mortality I get burned by either failed attempts and/or memory leaks.
Here's some test code showing my utter confusion: use strict; use warnings; package Mod; sub new { return bless [ 'meh' ], shift; } sub foo { return [ 0..$_[1]-1 ]; } package main; my $m = Mod->new; for ( 1..10000 ) { # my $v = foo($m,30); test($m,30); print "Iteration: $_\n" unless $_ % 10_000; } use Inline C => <<'EOC'; SV* foo(SV* mod,SV* upto) { SV* values; int count; int i; dSP; PUSHMARK(SP); XPUSHs(mod); XPUSHs(sv_mortalcopy(upto)); PUTBACK; count = call_method( "Mod::foo", G_SCALAR ); SPAGAIN; if ( count != 1 ) croak("Mod::foo didn't return a sole value."); values = POPs; PUTBACK; // Horrible, stops the warnings but causes leaks // SvREFCNT_inc(values); if ( SvTYPE(SvRV(values)) != SVt_PVAV ) croak("Mod::foo didn't return a reference to an array."); // printf("Reference count of [ref,array]: [%i,%i]\n",SvREFCNT(values),SvREFCNT((SV*)SvRV(values))); // return values; return sv_2mortal(values); } void test(SV* mod,SV* upto) { int i; SV* values; // values = foo(mod,upto); values = newSV(0); for ( i = 0; i < 10; i++ ) { sv_setsv(values,foo(mod,upto)); //Copying the array to a new reference ups its reference count to 2: SvREFCNT_dec((SV*)SvRV(values)); // emits warnings if ( SvIV(upto) != (int)(av_len( (AV*)SvRV(values) ))+1) croak("Length of array != %i",SvIV(upto)); } for ( i = 0; i < (int)(av_len( (AV*)SvRV(values) )) + 1; i++ ) { if ( i != SvIV((SV*)*av_fetch( (AV*)SvRV(values), i, 0 )) ) croak("Bad value"); } // printf("Ref count of [ref,array]: [%i,%i]\n",SvREFCNT(values),SvREFCNT((SV*)SvRV(values))); } EOC Thanks very much for any pointers, Blake