Perl:将新值重新分配给标量会覆盖RAM中的当前内容吗?

Law*_*ceC 7 variables perl scalar data-persistence

我正在使用Perl进行与安全相关的任务,并且想知道何时发表如下声明:

$test = "new value"

执行,是$test在RAM中覆盖创建的旧值?

如果没有,有没有办法强迫这种情况发生?

ike*_*ami 13

如果标量不是神奇的并且它有一个字符串缓冲区并且字符串适合字符串缓冲区,那么字符串缓冲区的那部分将被覆盖.

注意

$s = "abcdef";
$s =~ s/...//;
$s = "x" x length($s);
Run Code Online (Sandbox Code Playgroud)

在标量的缓冲区中留下"xxx\0ef\0".您需要缓冲区的长度,而不是缓冲区内字符串的长度.

我的意思是说,两者都没有

$s = undef;
$s = 123;
Run Code Online (Sandbox Code Playgroud)

会影响字符串缓冲区.它甚至不会被解除分配.类似地,将字符串分配给标量不会影响标量的其他字段,例如保存数字的字段.


我忘了如果将字符串赋给标量是a TEMP,则替换目标的缓冲区而不是被覆盖.

>perl -MDevel::Peek -e"my $s = 'abc'; Dump($s); $s = 'X' x length($s); Dump($s);"
SV = PV(0x348d54) at 0x1d3927c
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x349fac "abc"\0
  CUR = 3
  LEN = 12
SV = PV(0x348d54) at 0x1d3927c
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x349fac "XXX"\0     <-- same address
  CUR = 3
  LEN = 12

>perl -MDevel::Peek -e"my $s = 'abc'; Dump($s); $s = sub { 'X' x length($s); }->(); Dump($s);"
SV = PV(0x38d54) at 0x1c3930c
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x39fac "abc"\0
  CUR = 3
  LEN = 12
SV = PV(0x38d54) at 0x1c3930c
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x1c603fc "XXX"\0     <-- different address
  CUR = 3                        No overwriting.
  LEN = 12
Run Code Online (Sandbox Code Playgroud)


bvr*_*bvr 9

您可以使用Devel :: Peek模块来回答这类问题:

use Devel::Peek;

my $test = "value";
Dump($test);
$test = "new value";
Dump($test);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,你得到:

SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x18751cc "value"\0
  CUR = 5
  LEN = 12
SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x18751cc "new value"\0
  CUR = 9
  LEN = 12
Run Code Online (Sandbox Code Playgroud)

可以很容易地看出,在这种情况下,地址保持不变.正如其他人所指出的,如果你的字符串比缓冲区长LEN,那么数据将被重新分配:

my $test = "value";
Dump($test);
$test = "new value that is much longer";
Dump($test);
Run Code Online (Sandbox Code Playgroud)

yield(看到指针旁边的PV变化):

SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x18751cc "value"\0
  CUR = 5
  LEN = 12
SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x187cf74 "new value that is much longer"\0
  CUR = 29
  LEN = 32
Run Code Online (Sandbox Code Playgroud)