Ответ 1
Ваш анализ верен.
$ perl -MDevel::Peek -e'
my $x; $x .= "x" for 1..100;
Dump($x);
substr($x, 50, length($x), "");
Dump($x);
'
SV = PV(0x24208e0) at 0x243d550
...
CUR = 100 # length($x) == 100
LEN = 120 # 120 bytes are allocated for the string buffer.
SV = PV(0x24208e0) at 0x243d550
...
CUR = 50 # length($x) == 50
LEN = 120 # 120 bytes are allocated for the string buffer.
Не только строчные строки Perl, но даже свободные переменные, выходящие за пределы области видимости, не используют их повторно при следующем вводе области.
$ perl -MDevel::Peek -e'
sub f {
my ($set) = @_;
my $x;
if ($set) { $x = "abc"; $x .= "def"; }
Dump($x);
}
f(1);
f(0);
'
SV = PV(0x3be74b0) at 0x3c04228 # PV: Scalar may contain a string
REFCNT = 1
FLAGS = (POK,pPOK) # POK: Scalar contains a string
PV = 0x3c0c6a0 "abcdef"\0 # The string buffer
CUR = 6
LEN = 10 # Allocated size of the string buffer
SV = PV(0x3be74b0) at 0x3c04228 # Could be a different scalar at the same address,
REFCNT = 1 # but it truly the same scalar
FLAGS = () # No "OK" flags: undef
PV = 0x3c0c6a0 "abcdef"\0 # The same string buffer
CUR = 6
LEN = 10 # Allocated size of the string buffer
Логика заключается в том, что если вам понадобится память один раз, есть еще один шанс, который вам понадобится снова.
По той же причине назначение undef
скаляру не освобождает свой строковый буфер. Но Perl дает вам возможность освобождать буферы, если вы хотите, поэтому передача скаляра в undef
заставляет освобождать скалярные внутренние буферы.
$ perl -MDevel::Peek -e'
my $x = "abc"; $x .= "def"; Dump($x);
$x = undef; Dump($x);
undef $x; Dump($x);
'
SV = PV(0x37d1fb0) at 0x37eec98 # PV: Scalar may contain a string
REFCNT = 1
FLAGS = (POK,pPOK) # POK: Scalar contains a string
PV = 0x37e8290 "abcdef"\0 # The string buffer
CUR = 6
LEN = 10 # Allocated size of the string buffer
SV = PV(0x37d1fb0) at 0x37eec98 # PV: Scalar may contain a string
REFCNT = 1
FLAGS = () # No "OK" flags: undef
PV = 0x37e8290 "abcdef"\0 # The string buffer is still allcoated
CUR = 6
LEN = 10 # Allocated size of the string buffer
SV = PV(0x37d1fb0) at 0x37eec98 # PV: Scalar may contain a string
REFCNT = 1
FLAGS = () # No "OK" flags: undef
PV = 0 # The string buffer has been freed.