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.
Is that what I should do ?
If windows permits me to 'Safefree(c->suit);', then why won't (Mandrake-9.1) linux ?
Cheers, Rob
#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "INLINE.h"
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); }
MODULE = card_pl_6e8e PACKAGE = main
PROTOTYPES: DISABLE
SV * create_structref (s, v) SV * s int v
void clear_mem (p) SV * p PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; clear_mem(p); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */