in reply to Managing C library memory in XS

As long as you always know that something returned by record_get_person may not be freed by your program, you can attack the problem by having two classes, Person::OwnedByPerl and Person::OwnedByLibrary. The destructor for Person::OwnedByPerl would call free_person(), while Person::OwnedByLibrary would have no destructor.

Of course, you could also store that information of whether to free the person or not on the XS level by having a struct hold the person pointer and a flag whether the XS owns that person or not.

Replies are listed 'Best First'.
Re^2: Managing C library memory in XS
by petermogensen (Sexton) on May 05, 2014 at 13:27 UTC

    The destructor for Person::OwnedByPerl would call free_person(), while Person::OwnedByLibrary would have no destructor.

    That would solve the problem of not freeing memory which doesn't belong to you. It wouldn't solve the problem of holdning a Perl reference to an object which used memory already freed by Record::DESTROY call.

    Of course, you could also store that information of whether to free the person or not on the XS level

    I think that has the same problem. If I create Perl code like:
    sub find_person { my $record = new Record(); my $person = $record->get_person(); return $person; } my $p = find_person(); my $name = $p->name();
    ... then I would have an invalid-read. ... and Valgrind confirms it for me.

      Aaah - I didn't understand that connection. The easy approach here would be to let Perl do all your reference counting.

      Make the person a hash entry in your (Perl) Person class, and have ->get_person also store the (Perl) Record object in the Person hash. This is most easy done on the Perl side.

      This way, as long as the Person is alive, the Record object belonging to the Person is also alive. The person data structure will then also stay valid through the Record object.

        Yes... I that seems like an workable solution which ensures that any memory owning object is not freed before all references to contained objects are gone.

        It's a bit hard to maintain code wise though... isn't it? I mean... every perl method using an XS method must know which objects to keep a reference to. ... and that requires knowledge about how the XS code is implemented

        It basically does the same as I suggested with the NV field: Increment the refcnt on the record object and store a back-reference to it so it can be decremented with the person object has DETROY called. Only difference is doing that on the Perl side.

        I don't think doing it on the XS side like I proposed with abusing the NV field is difficult. Actually it's a lot less code. The question is how large a red light it lights up :-)

Re^2: Managing C library memory in XS
by ikegami (Patriarch) on May 05, 2014 at 20:56 UTC
    Having a flag rather than using two classes would make more sense.