Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Perl sometimes recycle references?

The following code:

use strict;
use warnings;

my @array = (0,1,2,3,4,5,6,7,8,9);
print "array ref is ".\@array."\n";

my @copy_refs;
for my $element(@array) {
    my @copy = @array;
    print "copy ref is ".\@copy."\n";
    push @copy_refs, \@copy;
}

produces the following output, as one might expect:

array ref is ARRAY(0x21ae640)
copy ref is ARRAY(0x21e2a00)
copy ref is ARRAY(0x21d7368)
copy ref is ARRAY(0x21d71e8)
copy ref is ARRAY(0x21d70c8)
copy ref is ARRAY(0x21d6fa8)
copy ref is ARRAY(0x21d6e88)
copy ref is ARRAY(0x21d6d68)
copy ref is ARRAY(0x21d6c48)
copy ref is ARRAY(0x21cf8a0)
copy ref is ARRAY(0x21cf780)

However, the same code, with push @copy_refs, \@copy; removed, produces the following output:

array ref is ARRAY(0x229e640)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)

Why is this?

like image 839
LongTP5 Avatar asked Mar 20 '26 07:03

LongTP5


1 Answers

Perl uses reference counting to determine when to free variables. A variable is freed as soon as nothing references it. Code blocks (e.g., subs and files) maintain a reference to the lexical variables declared within them while the variables are in scope, so variables normally get deallocated on scope exit.

In other words, my @copy allocates a new array. When the scope is exited, @copy gets freed if nothing else references it.

When you do push @copy_refs, \@copy;, @copy_refs references the array, so @copy isn't freed.

When you omit push @copy_refs, \@copy;, nothing references @copy, so it's freed. This leaves the memory available to be reused in the next loop pass.

Kinda.

As an optimization, if nothing references a variable when it goes out of scope, it's merely cleared rather than destroyed and recreated. So @copy is not being merely reallocated at the same location; it's actually the very same array that's been cleared.

like image 60
ikegami Avatar answered Mar 21 '26 21:03

ikegami



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!