in reply to Perl eats all memory when accessing hash/array refs wrong

The problem is that you are using a reference as index in an array. A reference used in numeric context returns the memory address of whatever this is pointing to. This usually is a big number, which means that Perl is going to create an array large enough to index on that position. Which will result in allocating lots of memory.

The effects are system dependent, and if you have lots of memory, and the reference happens to be a relative low address, you might even be lucky enough that Perl will be able to allocate the memory.

Abigail

  • Comment on Re: Perl eats all memory when accessing hash/array refs wrong

Replies are listed 'Best First'.
Re: Re: Perl eats all memory when accessing hash/array refs wrong
by demerphq (Chancellor) on Sep 25, 2003 at 11:24 UTC

    The problem is that you are using a reference as index in an array.

    I admit that this appears to be whats going on, But I do not understand how. I see no lookup of an array in that code.

    Heres some toying I did with the problem.

    #!perl -l use strict; use warnings; my $a = {child1 => [ {child2 => [ {child3 => [ {child4 => [1]} ]} ]} ] +}; print $a->{child1}{child2}{child3}; #cut off {child3} and no problem. print '$a:',ref $a; print '$a->{child1}:',ref $a->{child1}; print '$a->{child1}{child2}:',ref $a->{child1}{child2}; print '@{$a->{child1}}:',scalar @{$a->{child1}}; __END__ $a:HASH $a->{child1}:ARRAY $a->{child1}{child2}:HASH @{$a->{child1}}:28004977

    So it would appear that somehow $a->{child1}{child2} is being treated as an array lookup. But how? There is no array lookup involved.

    Id be interested to hear an explanation as to why this isnt a bug in perl.


    ---
    demerphq

      First they ignore you, then they laugh at you, then they fight you, then you win.
      -- Gandhi


      Pseudo-hashes are an experimental and soon-to-be-deprecated feature.

        Aha! Thanks very much. It wasn't obvious to me that this was a pseudo-hash lookup, but now that you point it out its quite clear. And from this example alone its a Good Thing that they are going to go away. Any array containing a hash as the 0 element gets magically treated as a pseudo hash. The fog clears....

        At the very least the pseudo-hash code should insist that the hash is composed of ONLY integer values, and certianly should NOT silently numerify the array ref. It should throw a fatal error there IMO. Anyway, we all know thats not going to happen, as they well be disappearing soon enough, but what an oversight.

        *sigh* and thanks. Good eye.


        ---
        demerphq

          First they ignore you, then they laugh at you, then they fight you, then you win.
          -- Gandhi


Re: Re: Perl eats all memory when accessing hash/array refs wrong
by tachyon (Chancellor) on Sep 25, 2003 at 11:16 UTC

    The problem is that you are using a reference as index in an array.

    How so? You can certainly see the effect with the attempt to access the first non existent key (but only on Linux) but could you explain that further.....

    C:\>type test.pl use Data::Dumper; my $a={ child1 => [ {child2 => [ { child3 => [ {child4 => [ 1 ] } ] } +] } ] }; print Dumper $a; print Dumper $a->{child1}; print Dumper $a->{child1}{child2}; print Dumper $a->{child1}{child2}{child3}; print Dumper $a->{child1}{child2}{child3}{child4}; C:\>perl test.pl $VAR1 = { 'child1' => [ { 'child2' => [ { 'child3' => [ { 'child4' => +[ + 1 +] } ] } ] } ] }; $VAR1 = [ { 'child2' => [ { 'child3' => [ { 'child4' => [ 1 ] } ] } ] } ]; $VAR1 = undef; $VAR1 = undef; $VAR1 = undef; C:\> [root@devel3 root]# cat test.pl use Data::Dumper; my $a={ child1 => [ {child2 => [ { child3 => [ {child4 => [ 1 ] } ] } +] } ] }; print Dumper $a; print Dumper $a->{child1}; print Dumper $a->{child1}{child2}; print Dumper $a->{child1}{child2}{child3}; print Dumper $a->{child1}{child2}{child3}{child4}; [root@devel3 root]# perl test.pl $VAR1 = { 'child1' => [ { 'child2' => [ { 'child3' => [ { 'child4' => +[ + 1 +] } ] } ] } ] }; $VAR1 = [ { 'child2' => [ { 'child3' => [ { 'child4' => [ 1 ] } ] } ] } ]; $VAR1 = undef; # hangs for 5 seconds here $VAR1 = undef; $VAR1 = undef; [root@devel3 root]#

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print