在for循环中声明变量不好?

时间:2016-08-10 04:17:09

标签: perl memory-leaks declaration

for $i (1..1000000)
{
    my $a = rand(10);
    my $b = rand(10);
    my $c = rand(10);
}

上述代码是否会在循环的每次迭代期间为$a$b$c分配新的内存位置,从而占用比以下代码更多的内存?

my ($a,$b,$c);
for $i (1..1000000)
{
    $a = rand(10);
    $b = rand(10);
    $c = rand(10);
}

1 个答案:

答案 0 :(得分:5)

(首先,$i不应是全局变量,因此应为for my $i (...)。其次,请勿使用名称$a$b,甚至在示例中都没有,因为它们是sort使用的特殊变量。)

该问题的天真答案是否定的,因为$a$b$c在到达块}的末尾时被释放,因此最终结果迭代的内存使用是零变化。

perl中的实际实现更加智能:它重用了$a / $b / $c的内存,因此它不必重复释放然后重新分配同一块记忆。 (当然,如果你创建一个对循环体之外的局部变量的引用,它就不能这样做,因为这个变量保持活着,即使它的名字超出了范围。)

您可以通过将循环更改为此来确认是这种情况:

for my $i (1 .. 5) {
    my $x = rand 10;
    my $y = rand 10;
    my $z = rand 10;
    print join(" ", \$x, \$y, \$z), "\n";
}

输出类似于

SCALAR(0x4a5788) SCALAR(0x4a5728) SCALAR(0x4a56c8)
SCALAR(0x4a5788) SCALAR(0x4a5728) SCALAR(0x4a56c8)
SCALAR(0x4a5788) SCALAR(0x4a5728) SCALAR(0x4a56c8)
SCALAR(0x4a5788) SCALAR(0x4a5728) SCALAR(0x4a56c8)
SCALAR(0x4a5788) SCALAR(0x4a5728) SCALAR(0x4a56c8)

表明内存位置在所有循环迭代中都是相同的。