Hi,

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 */





Reply via email to