4

When calling a C function from Perl, for example using Inline::C:

use feature qw(say);
use strict;
use warnings;
use Inline C => './test.c';

say "Calling test()..";
test();
say "Finished.";

where test.c is:

void test() 
{
    SV *sv_variable = newSVpv("test", 0);

    // do something..

    //SvREFCNT_dec(sv_variable); // free variable
    printf( "Returning from test()..\n");
    return;

}

The script seems to work fine whether I call SvREFCNT_dec(sv_variable) or not. According to perlguts:

To free an SV that you've created, call SvREFCNT_dec(SV*). Normally this call is not necessary

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
  • 2
    `newSVpv` starts with a REFCNT of 1. You can view this as `test()` gaining ownership of a reference. As the owner of the reference, `test()` must either reduce the var's REFCNT or transfer ownership of the var before exiting. So yes, `SvREFCNT_dec` should be called by `test()`. – ikegami Feb 26 '17 at 23:34

1 Answers1

4

Yes, you should decrement the refcount. (If you don't, there are no immediate bad effects, but you've created a memory leak.)

perlguts probably says this normally isn't necessary because most SVs aren't just used internally in C functions; they're part of structures reachable from Perl space or put on the stack.

But note that your code structure isn't exception safe: If any function in // do something throws, sv_variable will leak (because SvREFCNT_dec is never reached). This can be fixed by doing:

SV *sv_variable = sv_2mortal(newSVpv("test", 0));

sv_2mortal is like a deferred SvREFCNT_dec: It will decrement the reference count some time "later".

(If you're creating an SV from a string literal, newSVpvs("test") is better than newSVpv because it doesn't have to compute the length at runtime.)

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • 1
    So when using `sv_2mortal()` it does not matter if the variable is returned on the stack or not, it will work anyway? And Perl is going to free the variable when `test()` returns ( but before the `say "Finished."` statement in my example)? Since `perlguts` says *"An xV that is mortal has had its reference count marked to be decremented, but not actually decremented, until "a short time later". Generally the term "short time later" means a single Perl statement"* – Håkon Hægland Feb 25 '17 at 13:40
  • 2
    Re "*So when using sv_2mortal() it does not matter if the variable is returned on the stack or not, it will work anyway?"* Yes. /// Re "*And Perl is going to free the variable when test() returns*", If you use `SvREFCNT_dec`, it will be freed immediately (assuming no other reference to it exists). If you use `sv_2mortal`, it will be freed right after the caller has a chance to copy it (it if had been returned). /// Re "*but before the say "Finished." statement in my example*", Yes. – ikegami Feb 26 '17 at 23:32
  • 2
    Re "*But note that your code structure isn't exception safe*", C doesn't have exceptions, so that's not really an issue. There are `longjmps`, but if you're using those, you know to use the equivalent of `try`/`catch` to clean up after yourself. No reason to use `sv_2mortal`. – ikegami Feb 26 '17 at 23:37
  • 2
    Note that in situation where a callback is called multiple times in a row, the code doing the calls might postpone the deallocation of temps (mortals) to speed up the loop operation. (i.e. It might handle the temps once after all calls rather than after every call.) – ikegami Feb 27 '17 at 08:01
  • 1
    @ikegami The perl internals themselves use `longjmp`. E.g. if you call a function that (indirectly) triggers a warning and warnings have been fatalized (or there is a custom `__WARN__` handler that `die`s), a Perl exception is thrown, which manifests as a `longjmp`. – melpomene Mar 02 '17 at 16:00