Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: Perl XS: garbage-collecting my malloc'd buffer (grow)

by tye (Sage)
on Mar 03, 2003 at 17:09 UTC ( [id://240076]=note: print w/replies, xml ) Need Help??


in reply to Perl XS: garbage-collecting my malloc'd buffer

Your original code didn't have a memory leak. [ Update: Rather, it needn't have a memory leak. Just remove the "buffer = (char *)malloc(len);" which I skipped over when I read it. (: ]

When you tell XS that you have a "char *" input buffer, it pulls out a pointer to the string value (if any) stored in the scalar you pass in. So that buffer is allocated just like any other scalar string value buffer in Perl and is free()d in the same situations. So you don't need to worry about a memory leak.

You could think of your original code as "inconvenient" or even "dangerous" because it requires the caller to pass in length($buffer) or at least a value that is smaller than the size of the buffer allocated to the "buffer" scalar that is passed in.

But I'd probably fix that by forcing the scalar to contain a buffer of the specified size before calling the C function:

int my_xs_func(p_struct, OUTLIST buffer, len) void *p_struct; SV *buffer; int len; CODE: { char *buf = sv_grow( buffer, len ); /* was: char *buf = SvGROW( buffer, len ); */ RETVAL = my_func( p_struct, buf, len ); } OUTPUT: RETVAL
see perlguts for more on SvGROW() (see also perlxstut, perlxs, etc.) (:

Updated to match what I'd use based on the feedback below.

                - tye

Replies are listed 'Best First'.
Re: Re: Perl XS: garbage-collecting my malloc'd buffer
by Thelonius (Priest) on Mar 03, 2003 at 18:01 UTC
    I think that before you SvGROW you should call SvPV_force. Otherwise (at least this was once true) SvGrow will choke if there is not already a buffer. So, the code would be:
    CODE: { int dummylen; SvPV_force(buffer, dummylen); char *buf = SvGROW( buffer, len ); RETVAL = my_func( p_struct, buf, len ); }
      Yep, that's still the case. SvGROW checks xpv_len, which'll be some bizarre value if the SV's just an IV or NV. Undef might well give it fits too, at least so reads the 5.8.0 sources.

        Wouldn't calling sv_grow() directly fix that?

                        - tye

      That was how I had originally written the code in my head then I checked the Perl v5.6.0 source code for SvGROW() and saw that such wasn't needed. It might be a problem for Perl versions prior to that, however. I know I jumped through more hoops when I wrote similar XS code ages ago -- I was hoping it had just been my lack of understanding. (:

      Update: I was mostly checking sv_grow() which is what the SvGROW() macro calls. See elsewhere in this thread for why I'm wrong above.

                      - tye

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://240076]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (1)
As of 2024-04-23 16:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found