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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With