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.