Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

ethan (3163)

ethan
  reversethis-{ed. ... rap.nov.olissat}

Being a 25-year old chap living in the western-most town of Germany. Stuying communication and information science and being a huge fan of XS-related things.

Journal of ethan (3163)

Saturday August 16, 2003
04:42 AM

to memleak or not to memleak

[ #14155 ]

The following code should actually need more or less constant memory, right?

       
                my $str = "a";
                for (0 .. $i) {
                        $str->nextI; # string autoincrement: "z" becomes "aa"
                        print $str;
                }
       

But no, it doesn't. Depending on $i, it may eat well over 30meg. So naturally I suspected a memore-leak in my code and asked valgrind about it.

valgrind only finds 128 non-freed bytes, but those aren't by me but are allocated somewhere in the perl-interpreter. In my code, I naturally return a mortal SV and deallocate all my memory tidily. Very strange really.

Another thing I became aware of might be a problem with Perl's default typemaps.

        char *
        func ()
                PREINIT:
                        char *string;
                CODE:
                        string = func_that_returns_allocated_string();
                        RETVAL = string;
                OUTPUT:
                        RETVAL

The 'char*' typemap copies the string pointed to by RETVAL into an SV and returns it. The thing is the copying. Since it is copied, I need to free the original string somehow, but I don't see how this is possible. Initially I used a lot of these default typemaps to return values and in fact valgrind reported small leaks for each of them. Perhaps I have to use the 'CLEANUP' directive for that.

Now I changed it to:


        void
        func ()
                PREINIT:
                        char *string;
                PPCODE:
                        string = func_that_returns_allocated_string();
                        XPUSHs(sv_2mortal(newSVpvn(string, strlen(string))));
                        Safefree(string);
                        XSRETURN(1);

Anyway, this made the leaks go away (according to valgrind), so I guess I am on the right track here.

This didn't fix my problem with next and nextI though. :-(

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Rather than copying the malloc()ed string into an SV and then free()ing it, check out sv_usepvn which can directly take over the buffer. Sorry, I don't know the XS-fu to create a typemap to make your wrapper use this automatically.

    Maybe that useful function should be re-named sv_borg to make it stand out more.

    • [sv_usepvn]

      Nice! I was looking for something like that. In fact, I always blindly assumed that the 'char *' typemap would only copy the pointer and not the whole vector (till I realized that it does exactly that yesterday).

      I think this can be turned into a typemap easily. AFAIK, there is no default typemap for 'const char*' so I can use that.

      Maybe that useful function should be re-named sv_borg to make it stand out more.
       
      :-) Guess what: the curious Poison() macro did immediately spring into my