7

私はセキュリティ関連のタスクに Perl を使用していますが、次のようなステートメントがいつ表示されるのか疑問に思っています。

$test = "new value"

を実行すると、作成した古い値が$testRAM に上書きされますか?

そうでない場合、それを強制的に発生させる方法はありますか?

4

3 に答える 3

13

スカラーが魔法ではなく、文字列バッファーがあり、文字列が文字列バッファーに収まる場合、文字列バッファーのその部分が上書きされます。

ご了承ください

$s = "abcdef";
$s =~ s/...//;
$s = "x" x length($s);

スカラのバッファに "xxx\0ef\0" を残します。バッファ内の文字列の長さではなく、バッファの長さが必要です。

どちらでもないと言うつもりだった

$s = undef;
$s = 123;

文字列バッファに影響を与えます。割り当ても解除されません。同様に、文字列をスカラーに割り当てても、数値を保持するフィールドなど、スカラーの他のフィールドには影響しません。


TEMPスカラーに割り当てられている文字列が aの場合、ターゲットのバッファーは上書きされるのではなく置き換えられることを忘れていました。

>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
于 2011-07-30T18:07:43.563 に答える
9

Devel::Peekモジュールを使用して、この種の質問に答えることができます:

use Devel::Peek;

my $test = "value";
Dump($test);
$test = "new value";
Dump($test);

この場合、次のようになります。

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

この場合、アドレスが同じままであることは容易にわかります。他の人が指摘したように、文字列が buffers よりも長い場合LEN、データは再割り当てされます。

my $test = "value";
Dump($test);
$test = "new value that is much longer";
Dump($test);

得られます(変更された横のポインターを参照してください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
于 2011-07-30T19:22:50.173 に答える
3

の以前の値が何であったかによると思います$test

たとえば、新しい値がより長い場合、perl は realloc() (または同様のもの) を呼び出す必要があり、文字列が格納される場所を変更できます。

一般に、perl の文字列操作は可能な限り同じメモリを使用しているように見えますが、これが保証されているとは思いません。

スカラーの文字列バッファーのアドレスを取得できますunpack('J', pack('P', $s))。これは、スカラーに文字列が含まれていない場合 (文字列バッファーがある場合でも) は機能しません。

于 2011-07-30T18:06:31.623 に答える