在试图处理C级的参考时,我似乎无法弄清楚newRV_inc和之间的差异(在实践中)newRV_noinc.为此,我嘲笑了这个小Inline::C例子.
#!/usr/bin/env perl
use strict;
use warnings;
use Devel::Peek 'SvREFCNT';
my $arrayref_inc = make_arrayref_inc();
print "inc: ", SvREFCNT($arrayref_inc), "\n";
my $arrayref_noinc = make_arrayref_noinc();
print "noinc: ", SvREFCNT($arrayref_noinc), "\n";
use Inline C => <<'END_C';
SV* make_arrayref_inc () {
AV * array = newAV();
SV * arrayref = newRV_inc((SV *)array);
return arrayref;
}
SV* make_arrayref_noinc () {
AV * array = newAV();
SV * arrayref = newRV_noinc((SV *)array);
return arrayref;
}
END_C
Run Code Online (Sandbox Code Playgroud)
得到:
inc: 1
noinc: 1
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮助我理解为什么这段代码会这样做?
当你调用时,SvREFCNT($arrayref)你得到的是arrayref的引用计数,而不是它引用的数组. newRV_inc增加引用计数array,而newRV_noinc不是.但这对参考计数没有任何影响arrayref.(我认为你不能得到带有Devel :: Peek的arrayref引用的数组的引用计数.)
AV* array = newAV()创建具有的1.在引用计数一个新的数组make_arrayref_inc,newRV_inc递增,为2,而与为1的引用次数创建一个新的SV(该数组引用)这引起了内存泄漏,因为你不递减array退出函数之前的引用计数.Perl认为它有2个引用,但它实际上只有1个,所以在解释器关闭之前它永远不会被垃圾收集.
这就是您通常newRV_noinc在代码中使用的原因,该代码返回对新创建的值的引用.它比使用更有效newRV_inc,然后SvREFCNT_dec.您可以newRV_noinc将AV的所有权转移array到arrayref.