gpt4 book ai didi

perl - refaddr 返回的值是永久的吗?

转载 作者:行者123 更新时间:2023-12-01 10:43:12 24 4
gpt4 key购买 nike

根据 Scalar::Util's documentation , refaddr 是这样工作的:

my $addr = refaddr( $ref );

If $ref is reference the internal memory address of the referenced value is returned as a plain integer. Otherwise undef is returned.

但是,这并没有告诉我 $addr 是否是永久的。引用的 refaddr 会随时间变化吗?例如,在 C 语言中,运行 realloc 可以更改动态内存中存储的内容的位置。这与 Perl 5 类似吗?

我问是因为我想制作一个 inside-out object ,我想知道 refaddr($object) 是否会成为一把好 key 。例如,在 XS 中编程似乎最简单。

最佳答案

首先,不要重新发明轮子;使用 Class::InsideOut .


它是永久的。它必须是,否则以下将失败:

my $x;
my $r = \$x;
... Do something with $x ...
say $$r;

标量在固定位置有一个“头”。如果 SV 需要升级(例如保存一个字符串),它是第二个内存块,称为“主体”,将发生变化。字符串缓冲区仍然是第三个内存块。

Layout of an SVt_PVIV scalar

$ perl -MDevel::Peek -MScalar::Util=refaddr -E'
my $x=4;
my $r=\$x;
say sprintf "refaddr=0x%x", refaddr($r);
Dump($$r);
say "";

say "Upgrade SV:";
$x='abc';
say sprintf "refaddr=0x%x", refaddr($r);
Dump($$r);
say "";

say "Increase PV size:";
$x="x"x20;
say sprintf "refaddr=0x%x", refaddr($r);
Dump($$r);
'

refaddr=0x2e1db58
SV = IV(0x2e1db48) at 0x2e1db58 <-- SVt_IV variables can't hold strings.
REFCNT = 2
FLAGS = (PADMY,IOK,pIOK)
IV = 4

Upgrade SV:
refaddr=0x2e1db58
SV = PVIV(0x2e18b40) at 0x2e1db58 <-- Scalar upgrade to SVt_PVIV.
REFCNT = 2 New body at new address,
FLAGS = (PADMY,POK,IsCOW,pPOK) but head still at same address.
IV = 4
PV = 0x2e86f20 "abc"\0 <-- The scalar now has a string buffer.
CUR = 3
LEN = 10
COW_REFCNT = 1

Increase PV size:
refaddr=0x2e1db58
SV = PVIV(0x2e18b40) at 0x2e1db58
REFCNT = 2
FLAGS = (PADMY,POK,pPOK)
IV = 4
PV = 0x2e5d7b0 "xxxxxxxxxxxxxxxxxxxx"\0 <-- Changing the address of the string buffer
REFCNT = 2 doesn't change anything else.
CUR = 20
LEN = 22

关于perl - refaddr 返回的值是永久的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28763223/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com