in reply to Dangling Pointer::perl referrence

but the referrence still exist

Of course. You never changed $arr_r.

Is it same as "Dangling Pointer" in C???

No. A dangling pointer is a pointer to something that doesn't exist anymore. You didn't even try to get rid of the array — undef simply empties it — so there's definitely no dangling pointer.

Even if you tried to get rid of the array (like in the following example), you wouldn't get a dangling. The reference would keep it alive until you got rid of the reference too.

my $ref; { my @array = 'element'; $ref = \@array; } # Because the array is lexically scoped (my), # the array would normally be freed here*, # but the reference is keeping it alive. print "$ref->[0]\n"; # Prints 'element' $ref = undef; # The scalar stops referencing the array, # so it's freed here.

Think of my as new.

my @outer; for (1..2) { my @inner = "pass $_"; push @outer, \@inner; } print "@{ $outer[0] }\n"; # pass 1 print "@{ $outer[1] }\n"; # pass 2

But realize that Perl will get rid of something automatically as soon as noone needs it anymore. For example, if that entire piece of code was in a sub, @outer and the two @inner would get freed by the subroutine exit code*.

One catch: Perl sometimes doesn't realize nothing needs a value anymore. It occurs when you have a reference cycle like the following:

for (1..10) { my $r1; my $r2 = \$r1; my $r3 = \$r2; $r1 = \$r3; } # You have just leaked 30 variables.

* — Aside from optimisations that would only confuse the issue.

Replies are listed 'Best First'.
Re^2: Dangling Pointer::perl referrence
by Anonymous Monk on Feb 17, 2010 at 23:05 UTC
    Hi ikegami,

    Thanks for your reply. From the example you given, it means that the referrence will keep the array alive unless I destroy the referrence too (as below)

    my $ref; { my @array = 'element'; $ref = \@array; }
    But what if I use like below
    { my @array = 'element'; } $ref = \@array; print "$ref\n";

    OR

    $ref=\@arr; #### @arr doesn't excist at all print "$ref\n";
    In both this case I get a output like below

    ARRAY(0x1830614)

    Now where it's referring too? There is no such variable ... means no such memory location?

    Thanks

      { my @array = 'element'; } $ref = \@array; print "$ref\n";

      That doesn't compile, at least not under use strict; which you should be using. The reason is the second @array is a completely different variable than the first. It's package variable $main::array, aka a global variable. Global variables, by definition and by design, don't get freed before the program exits (without taking some intentional action to remove it from the symbol table). Think of extern int a; in a .h.

      Now where it's referring too? There is no such variable ... means no such memory location?

      Global variables get created simply by using them. By taking a reference to previously non-existant @main::array (2nd snippet) or @main::arr (3rd snippet), they get created. Well, technically, they already existed in those snippets because the parser created them when it noticed they will be used. The following code peeks at the symbol table where package variables reside:

      >perl -E"say *array{ARRAY}||0;" 0 >perl -E"say *array{ARRAY}||0; @array; say *array{ARRAY}||0;" ARRAY(0x182a24c) ARRAY(0x182a24c) >perl -E"say *array{ARRAY}||0; @{'array'}; say *array{ARRAY}||0;" 0 ARRAY(0x238b24)

      The parser created @main::array when it compiled @array
      The runtime created @main::array when it evaluated @{"array"}

      Different to C there are global variables that spring into existence the moment you refer to them. So when perl executes $ref = \@array; in your second example, @array is a new global (but empty) variable that has nothing in common with the 'my @array' variable except for the name.

      If you had a line 'use warnings;' at the beginning of your script (a practice very recommended), you would have seen the following warning: "Name "main::array" used only once: possible typo at ./t7.pl line 6". Ok, not that easy to decipher, but once you know that global variables are living in name spaces, the default one being called 'main::', you would have a clue about what went wrong

      If you also had a line 'use strict;' at the beginning of your script (a practice very recommended for any script larger than a few lines) your script would have aborted at the compilation stage with error messages about global variables.