pmtolk has asked for the wisdom of the Perl Monks concerning the following question:

I am wondering about the dynamic memory allocation for arrays and hashes which dont seem to change a pointers reference to it when they grow (I could be wrong)? What does the pointer actually point to and what does that point to on down until we hit actual memory?
%hash; $hash{'name'}=1; $ptr=\$hash{'name'}; print $$ptr; for(1..1000){ $hash{"$_"}=$_; } print $$ptr;
I modified waters code
my $x = {}; $x->{'named'} = 'watermelon'; print $x->{'named'} , " is quite delicious\n"; my $ref = \ $x->{'named'}; $$ref = 'cantelope'; print $x->{'named'} , " is quite delicious\n"; $x->{'named'}='mango'; print $x->{'named'} , " is quite delicious\n"; print $$ref , " is quite delicious\n"; for(1..10){ $x->{'named'}=$_; print "$$ref $x->{'named'}\n"; }
$$ref did print mango and thus when what it pointed to changed it pointed to the changed value. So once a pointer points to an object and that object gets moved in physical memory due to (memory allocation or optimization or something) then the pointer will still point to the correct place. (until garbage collection or its assigned a different value, I am guessing) thanks all

Replies are listed 'Best First'.
Re: pointer memory and dynamic memory
by Enlil (Parson) on Oct 13, 2004 at 08:05 UTC
Re: pointer memory and dynamic memory
by BrowserUk (Patriarch) on Oct 13, 2004 at 08:14 UTC

    This

    $ptr=\$hash{'name'}

    Is a reference to the value of the element of %hash named 'name'. All your code does after you take that reference is add new elements to %hash. The value of $hash{name} doesn't change, so it doesn't move.

    But even if you changed the value of $hash{name}='fred';, the value you previously assigned to $ptr would not change as a result, and it would still point to the original value. Indeed, the original value will remain where it is and not be garbage collected until you assign something else to $ptr, or $ptr goes out of scope and is itself GC'd.

    To get an understanding of the internal structure of Perl's datastructures work at the C-level, take a look at Gisle Aas' amazing Perl Guts Illustrated.

    The main thing to note though, is that Perl's references have some superficial resemblence to C-style pointers, but thinking of them, or trying to use them in that way is not the thing to do. If you have a C++ background, then thinking of them as roughly equivalent to C++ references is a more intuative analogy, and will get you into less problems.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: pointer memory and dynamic memory
by ccn (Vicar) on Oct 13, 2004 at 08:02 UTC
Re: pointer memory and dynamic memory
by Corion (Patriarch) on Oct 13, 2004 at 08:09 UTC

    For a quick start on how Perls memory management and memory layout work, see Perlguts illustrated. Your language indicates that you are coming from a C background - the Perl data types like reference and array don't match up directly with C pointers and arrays - there is magic happening inbetween so that the reference counting etc. works.

    As a very short start to understand Perlguts Illustrated, a scalar is represented mostly by an SV, and an array by an AV.

Re: pointer memory and dynamic memory
by ikegami (Patriarch) on Oct 13, 2004 at 16:31 UTC

    There are three problems.

    1) You can make a reference out of hashes, arrays, scalars, functions, code, globs/IO and constants, but you can NOT create references to hash elements or array elements.
    $ptr = \$hash{'name'};
    is the same as
    $ptr = \($hash{'name'});
    which (in this case) is the same as
    $ptr = \1;
    which is a reference to a constant. Wouldn't
    $key = 'name'; print $hash{$key};
    suffice?

    2) "$_" can be written as simply $_.

    3) Do you think that loop will overwrite the value at $hash{'name'}? Numbers are automatically converted to strings and become just another key:

    $hash{'name'} = 1; $hash{0} = 2; $hash{1} = 3; $hash{'1'} = 4; $\=$/; # Adds "\n" to every print. $,=", "; # Seperate printed fields with commas. print(keys(%hash)); # prints: name, 0, 1 (in random order) print($hash{'name'}); # prints: 1 print($hash{0}); # prints: 2 print($hash{1}); # prints: 4 print($hash{'1'}); # prints: 4
      Maybe I am missing your point, but what do you mean, 'you cant take a reference of a hash element'? Why not?
      use strict; my $x = {}; $x->{a}->{b}->{c}->{d} = 'watermelon'; print $x->{a}->{b}->{c}->{d} , " is quite delicious\n"; my $ref = \ $x->{a}->{b}->{c}->{d}; $$ref = 'cantelope'; print $x->{a}->{b}->{c}->{d} , " is quite delicious\n";
      And when you say, why would you want a reference to a hash or array element, when you can just say $x{key} or $y[$index]? I'd answer, one reason is that you may be dealing with something expects a reference to a scalar.

      For example, think about implementing a toy spreadsheet in Tk. (Scary thought!) A reasonable data structure for a toy implementation would be an LOL of scalars, with references to each array element bound into a TK widget for display and updating. You'd need refs to every cell because (in this case) Tk wants refs.

        It's a fine distinction, but

        $p = \$ary[ 2 ];

        is a reference to the scalar that is currently assigned to the third element of the array, not a reference to the third element of the array. If you assign through the reference, the array elements value will change, but only because the scalar that is the current value has changed.

        Too subtle? The clincher is that having taken the reference $p above, if you assign a value to

        $ary[ 2 ] = 'anything';

        the value referenced by $p doesn't change! The value of $ary[ 2 ] does.

        Hence, when you take a reference to an array element, you are taking a reference to the scalar that is that array element's current value.

        References from hash elements are the same, they point to the scalar that is the current value of that element. For a reference to point to the hash element itself, it would need (somehow) to reference both the key and the value, and continue to point to the current value of the element after the value of the element has been reassigned--not continue to point to the old value as currently.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: pointer memory and dynamic memory
by Anonymous Monk on Oct 14, 2004 at 10:47 UTC
    always try running your code with the -w switch:

    in your code:

    $ar[2]=10;
    you probably meant:
    $ary[2]=10;
    --Lance