in reply to XS malloc and free

Googling for "Free to wrong pool" shows that this error is specific to Perl, so your call to free() is calling Perl's own free() but surely your library isn't calling Perl's own malloc(). And my keen insight tells me that this is probably due to a C-preprocessor macro. So I chdir to perl/lib/CORE and "grep free *.h" and get:

XSUB.h:# define free PerlMem_free

which is unfortunate. Preventing XS routines from being able to easily choose which malloc system they want to use (Perl's or C's -- which are sometimes the same) is not the best idea.

In the meantime, you can "#undef free" before your call to free() to work around the problem (but don't use "free" any further down in your code, even indirectly via some other obscure C-preprocessor macro).

- tye        

Replies are listed 'Best First'.
Re^2: XS malloc and free (whose)
by BrowserUk (Patriarch) on Feb 07, 2006 at 20:07 UTC

    If I got the function pointer syntax right then something like this would be a workaround maybe?

    void (perls_free)( void*p ) = &free; #undef free // free() should now refer to the crt free() and use perls_free() for +XS

    Though the long term solution would be to remove the #define from the header file in favour of Safefree().

    That said, the whole area of memory allocation functions and macro's in the Perl codebase is a mess. Sometime last year I did a not totally crude grep and eliminate duplicates process on the sources and discovered that between the 4 basic functions--malloc(), calloc(), realloc() & free()--there were (from memory) 114 different ways of calling them through the multiplicitous variations of functions and macros. It's truely amazing that there are many more memory problems than there are.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      I think you are missing a "*":

      void (*perls_fre­e)( void*p ) = &free; #undef free

      But that still risks the second half of my warning:

      (but don't use "free" any further down in your code, even indirectly via some other obscure C-preprocessor macro).

      which seems rather difficult to avoid with any certainty given your assessment of the current messiness. :)

      Update: BTW, I am aware that the "&" is "optional", but I consider this simply to be a mistake on the part of the ANSI C definers. (:

      - tye        

        I knew it didn't look right.

        How about doing things the other way around. Take an alias for the CRT free() function prior to including XSUB.h?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^2: XS malloc and free (whose)
by ikegami (Patriarch) on Feb 07, 2006 at 19:15 UTC
    Not easy indeed. None of the following work:
    #define d a #include <stdio.h> void a() { printf("a\n"); } void b() { printf("b\n"); } int main() { a(); #define a b a(); (*&a)(); /* \a(); */ #define c a c(); d(); return 0; }

      Of course not. (: The C preprocessor is mostly just text substitution and is defined to not care about the order in which things are defined.

      A more interesting case that also doesn't work is:

      #include <stdio.h> void flee(int i) { printf("flee(%d)\n",i); } void perlFlee(int i) { printf("perlFlee(%d)\n",i); } int main() { flee(1); #define flee perlFlee flee(2); #define _stitch(a,b) a ## b #define Free(x) _stitch(fl,ee)( x ) Free(3); return 0; }

      Which produces "perlFlee(3)" as its last line of output.

      And this tenancity of the C preprocessor is why (at least when the idea of XS came about), there should have been (similar to several other changes that were made for similar reasons) a global s/\bfree\b/Perl_free/, and s/\bmalloc\b/Perl_malloc/g done to the Perl source code so "#define free..." could be eliminated (replaced with "#define Perl_free free" for some systems, of course).

      - tye