On Thu, Feb 12, 2004 at 12:45:29PM +1100 Sisyphus wrote: > Below is a very simple Inline::C script - and, in case it's useful, > below my sig is the XS file that Inline autogenerates from that script. > > ----- start card.pl ----- > use Inline C => <<'EOC'; > > typedef struct { > SV * suit; > int value; > } Card; > > > SV * create_structref(SV * s, int v) { > Card * cptr; > New(123, cptr, sizeof(Card), Card); > if(cptr == NULL) croak("Failed to allocate memory"); > cptr->suit = s; > cptr->value = v; > return sv_setref_pv(newSViv(0), Nullch, cptr); > } > > void clear_mem(SV * p) { > Card* c = (Card *)SvIV(SvRV(p)); > printf("Clear_mem called\n"); > Safefree(c->suit); > /* c->value is an int, and not to be Safefreed */ > Safefree(c); > } > > EOC > > $s_index = int(rand(4)); > $s = ('Hearts', 'Clubs', 'Diamonds', 'Spades')[$s_index]; > $v = int(rand(13)) + 1; > > $c = create_structref($s, $v); > > clear_mem($c); > > __END__ > ----- end card.pl ------ > > On win32, there's no problem with that (perl 5.6.1, 5.8.0, and 5.8.2). > > On linux, where I have only perl 5.8.0, it prints: > > Clear_mem called > Segmentation fault > > I can get rid of the Segmentation fault by commenting out > 'Safefree(c->suit);' in the 'clear_mem()' function.
That is what I would expect. You pass $v to create_structref and store a pointer to it in c->suit. You should only manually free it when you copied the SV. Something like that: SV * create_structref(SV * s, int v) { Card * cptr; New(123, cptr, sizeof(Card), Card); cptr->suite = sv_mortalcopy(s); cptr->value = v; ... } void clear_mem(SV *p) { Card *c = (Card*)SvIV(SvRV(p)); sv_free(c->suit); Safefree(c); } Copying the SV is a good idea anyways because otherwise c->suit is destroyed when perl garbage-collects $v. If you don't want to create a copy, you should increment the refcount of 's' in create_structref. In this case you should also be able to store a pointer to s in your structure. 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