2
votes

Assume I have a muti-level hash:

$class->{'key1'}->{'key2'}->{$key3}->{'string'}->{$key5},
where $class->{'key1'}->{'key2'}->{$key3}->{'string'}->{$key5}
equals to some integer number.
$key3 can be class name like "music", "english"...
$key5 can be student name like "mary", "luke"...

Will the following operation release all the memory under level $key3="music"? i.e. will the memory assigned to $key5 be released?

$current_class = $class->{'key1'}->{'key2'}->{"music"};
$current_class = undef;

Update:

thanks both. My understanding between delete and undef is: delete will remove the entry of key='music'

so $class->{'key1'}->{'key2'}->{"music"} will not exist. while undef will set value of $class->{'key1'}->{'key2'}->{"music"} as undef. but entry of key='music' is still there but the value of it will be undef so $class->{'key1'}->{'key2'}->{"music"} = undef.

so I should delete the entry, is it correct?

but do you mean

undef $class->{'key1'}->{'key2'}->{"music"};

and

$class->{'key1'}->{'key2'}->{"music"} = undef;

are different?

3

3 Answers

3
votes

No. In general scalar assignments are copy-by-value. To release the reference to this object's memory, you would have to say something like

$class->{'key1'}->{'key2'}->{"music"} = undef;       # 2nd,3rd --> are optional
delete $class->{'key1'}{'key2'}{"music"};

Assigning undef to an appropriate reference will also work.

$current_class_ref = \$class->{'key1'}{'key2'}{"music"};
$$current_class_ref = undef;
3
votes

No; the undef operation shown will not release all the memory.

That was easy. What's harder is "How do I release the memory?", and I think one answer is:

undef $class->{'key1'}->{'key2'}->{"music"};

Another (this is Perl!) might be:

delete $class->{'key1'}->{'key2'}->{"music"};

In both cases, Perl's reference counting might spot something else also using some value, in which case that value won't be released until there are no references left. However, if the only references are the ones in the multi-level hash, the memory should be released for reuse.

0
votes

Perl has reference counting garbage collector.

$ cat test.pl

#!/usr/bin/perl
use strict;
package Cat;
sub new { my ($class,$name) = @_; print "cat $name here\n"; bless \$name, $class; }
sub DESTROY { my $self = shift; print "  cat $$self gone\n"; }

package main;
my $ref->{aaa}->{bbb}->{ccc} = new Cat 'Alfred';
print  "111111\n";
$ref->{aaa} = 'qweqwe';
print  "222222\n";

$ ./test.pl

cat Alfred here
111111
  cat Alfred gone
222222