Должен ли я вызвать SvREFCNT_dec() для SV, который не будет возвращен Perl в стеке?

При вызове функции C из Perl, например, используя Inline::C:

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

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

где test.c является:

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

    // do something..

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

}

Сценарий, кажется, работает нормально, если я позвоню SvREFCNT_dec(sv_variable) или нет. В соответствии с perlguts:

Чтобы освободить созданный вами SV, вызовите SvREFCNT_dec(SV*). Обычно этот звонок не нужен

1 ответ

Решение

Да, вы должны уменьшить счет. (Если вы этого не сделаете, немедленных негативных эффектов нет, но вы создали утечку памяти.)

Perlguts, вероятно, говорит, что это обычно не нужно, потому что большинство SV не просто используются внутри в функциях C; они являются частью структур, доступных из пространства Perl или помещаемых в стек.

Но обратите внимание, что ваша структура кода не является исключительной безопасностью: если какая-либо функция в // do something броски, sv_variable будет течь (потому что SvREFCNT_dec никогда не достигается). Это можно исправить, выполнив:

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

sv_2mortal это как отложенный SvREFCNT_dec: Он уменьшит счетчик ссылок через некоторое время "позже".

(Если вы создаете SV из строкового литерала, newSVpvs("test") лучше, чем newSVpv потому что он не должен вычислять длину во время выполнения.)

Другие вопросы по тегам