5

I am absolutely new to Perl XS.

My simple testfunction gets a string and appends something. In Perl is is a scalar-string in and one out.

In the function I have a malloc. Whats the correct way to free the mem?

SV *foo (str)
   SV *str
CODE:
    unsigned char *strbuf;
    size_t strlen;
    strbuf = (unsigned char *) SvPV (str, strlen);

    int n = strlen + 10;
    unsigned char *buf = malloc (n);    

    strncpy (buf, strbuf, strlen);
    strncat (buf, "0123456789", 10);

    RETVAL = newSVpv (buf, n);
OUTPUT:
    RETVAL

thanks! Chris

chris01
  • 10,921
  • 9
  • 54
  • 93
  • 2
    I'm pretty new to XS, too, but I think you want to create a new scalar and then call [`sv_catpv`](http://perldoc.perl.org/perlapi.html#sv_catpv) or similar, so Perl manages the memory. – ThisSuitIsBlackNot Jul 12 '16 at 20:13
  • It is just an example. Please ignore the purpose of my sample. The question was about the malloc. – chris01 Jul 12 '16 at 20:20
  • 4
    The [perlguts](http://perldoc.perl.org/perlguts.html#Working-with-SVs) section documents several approaches to handling memory management. You could directly allocate an SV with the correct size and work with that instead of using malloc(). – Diab Jerius Jul 12 '16 at 20:23
  • 4
    In your case, since `buf` isn't needed after the `newSvpv` call, you can free it. Note that you should use the Perl provided macros for allocating and freeing memory. See [perlguts: Memory Allocation](http://perldoc.perl.org/perlguts.html#Memory-Allocation) – Diab Jerius Jul 12 '16 at 20:31
  • 1
    Also, have a look at the `perlclib` manpage. It lists lots of macros and functions that Perl offers to replace clib ones, for portability between operating systems and Perl versions. – Calle Dybedahl Jul 13 '16 at 10:27
  • @DiabJerius It's perfectly fine to use malloc/free in this case. For example, if you write a wrapper for a C library, that's what the library typically does anyway. – nwellnhof Jul 13 '16 at 10:34
  • @nwellnhof, there's a comment in the perlguts docs: "All memory meant to be used with the Perl API functions should be manipulated using the macros described in this section" which seems to indicate that if you can, you should. I agree, if you're handed a pointer to memory from someone else's codel, then there's not much you can do. – Diab Jerius Jul 13 '16 at 15:31
  • @DiabJerius You only have to use `Newx` for functions like `sv_usepvn` which directly assign a memory area. Typically, you use functions like `sv_setpvn` which make a copy of the buffer's content. In this case, it doesn't matter how the buffer was allocated. – nwellnhof Jul 14 '16 at 19:16

1 Answers1

4

newSVpv creates an internal copy of the string, so you can simply free the memory by calling free after assigning to RETVAL.

nwellnhof
  • 32,319
  • 7
  • 89
  • 113