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

This is a weird one, or at least it seems that way to me.

Granted though, I'm feeling like I'm missing something very obvious. So I may just be dumb, here.

Here's the scenario: I have the following code. It looks fairly straightforward: I create a new, empty list, then try to assign to element 10. That works fine. Then I dump out the array with Data::Dumper.

Then I create a new variable, assign a dummy string to it, and try to dump out my original array, again.

And I get a core dump, along with a bunch of "Attempt to free unreferenced scalar." warnings. How many? 10. Which is how many undefined elements are in my array, before the 11th element, which I defined.

Now to be honest, I *think* I can see what's going on: I create a new array, then fill in the 11th element, but leave the first 10 elements undefined. What seems to be happening is that Perl is getting rid of elements 0-9 (dropping their reference count to 0, then reclaiming the memory. Then Perl tries to write the data for the new variable ($base) over the memory originally held by my (still in scope) array.

So, the question: can anyone reproduce my results, which I've posted below? I'm running Perl5.005_03:

Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration: Platform: osname=linux, osvers=2.2.5-22smp, archname=i386-linux
So it's possible that this is a weird bug on my machine, and also possible that it's a bug in my version of Perl, fixed in 5.6. Who knows. Can anyone reproduce it, and if so, is it fixed in 5.6? (I don't have 5.6). Here's the code:
#!/usr/bin/perl -w use strict; use Data::Dumper; my @comps; $comps[10] = "foo bar"; print Dumper \@comps; my $base = "Foo bar"; print Dumper \@comps;
And the results:
$VAR1 = [ undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, 'foo bar' ]; Bizarre copy of ARRAY in aassign at /usr/lib/perl5/5.00503/Data/Dumper +.pm line 207. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Segmentation fault (core dumped)
Thanks.

Replies are listed 'Best First'.
(kudra: the prob isn't your computer) RE: Core Dumping with Arrays
by kudra (Vicar) on Sep 08, 2000 at 14:16 UTC
    Just to verify what Corion said, I decided to try the same version of perl you used, but on a different operating system (FreeBSD 4.0-STABLE). The result was a seg fault. I tried perl 5.6 on FreeBSD 4.0-STABLE and had no problems with the program, so I think we can pretty much say it's that perl version, not your machine. Here's the output from the failed test:
    [first dumper removed] Attempt to free unreferenced scalar at /usr/libdata/perl/5.00503/mach/ +Data/Dumper.pm line 350. Segmentation fault(core dumped)

    I also tested the problematic perl version on FreeBSD 4.0-RELEASE, just because. Here's the output in case anyone is interested:

    [first dumper removed] perl in free(): warning: junk pointer, too high to make sense. Use of uninitialized value at /usr/libdata/perl/5.00503/overload.pm li +ne 97. Use of uninitialized value at /usr/libdata/perl/5.00503/overload.pm li +ne 99. Use of uninitialized value at /usr/libdata/perl/5.00503/overload.pm li +ne 97. Use of uninitialized value at /usr/libdata/perl/5.00503/overload.pm li +ne 99. Use of uninitialized value at /usr/libdata/perl/5.00503/overload.pm li +ne 97. Use of uninitialized value at /usr/libdata/perl/5.00503/overload.pm li +ne 99. Use of uninitialized value at /usr/libdata/perl/5.00503/overload.pm li +ne 97. Use of uninitialized value at /usr/libdata/perl/5.00503/overload.pm li +ne 99. Use of uninitialized value at /usr/libdata/perl/5.00503/overload.pm li +ne 90. Use of uninitialized value at /usr/libdata/perl/5.00503/mach/Data/Dump +er.pm line 229. Use of uninitialized value at /usr/libdata/perl/5.00503/mach/Data/Dump +er.pm line 254. Segmentation fault(core dumped)
Re: Core Dumping with Arrays
by gregorovius (Friar) on Sep 08, 2000 at 11:37 UTC
    This is what I get when I run it on ActiveState 5.6 under NT:
    $VAR1 = [ undef, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, 'foo bar' ]; $VAR1 = [ undef, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, ${\$VAR1->[0]}, 'foo bar' ];
    So it works on 5.6. It's funny how the empty elements point to the undef at 0. If you put something there then the empty ones will point to the first empty one, which will be given undef: (What would be the advantage of doing it this way, instead of putting undef on all, as they had on 5.005?)
    #!/usr/bin/perl -w use strict; use Data::Dumper; my @comps; $comps[10] = "foo bar"; $comps[0] = "foo bar"; $comps[4] = "foo bar"; print Dumper \@comps; my $base = "Foo bar"; print Dumper \@comps; outputs: $VAR1 = [ 'foo bar', undef, ${\$VAR1->[1]}, ${\$VAR1->[1]}, 'foo bar', ${\$VAR1->[1]}, ${\$VAR1->[1]}, ${\$VAR1->[1]}, ${\$VAR1->[1]}, ${\$VAR1->[1]}, 'foo bar' ]; $VAR1 = [ 'foo bar', undef, ${\$VAR1->[1]}, ${\$VAR1->[1]}, 'foo bar', ${\$VAR1->[1]}, ${\$VAR1->[1]}, ${\$VAR1->[1]}, ${\$VAR1->[1]}, ${\$VAR1->[1]}, 'foo bar' ];
RE: Core Dumping with Arrays
by Corion (Patriarch) on Sep 08, 2000 at 11:46 UTC

    perl -v gives me

    This is perl, version 5.005_02 built for i586-linux
    and running your code produces the following (expected) results :
    $VAR1 = [ undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, 'foo bar' ]; $VAR1 = [ undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, 'foo bar' ];
    So it's something they broke between 5.005_02 and 5.005_3. Weird.

Re: Core Dumping with Arrays
by reptile (Monk) on Sep 08, 2000 at 19:50 UTC

    Running 5.00502 I got the same thing. I looked a little further into it out of curiosity. Dumper does an odd thing if it gets something that's not a reference: it makes it a reference and tries again. This is the problem right here. A slightly different approach:

    my @comps; $comps[10] = "foo bar"; my $foo = \$comps[0]; my $bar = \$comps[5]; my $baz = \$comps[10]; print "$foo $bar $baz\n"; __END__ UNKNOWN(0x813e940) UNKNOWN(0x813eac8) SCALAR(0x80c84b4) Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Attempt to free unreferenced scalar. Segmentation fault (core dumped)

    Dumper is trying to take a reference to an undefined value here, and that's apparently not something the 5.005 series likes too much. I'm not sure at all what's causing the core dump. If I simply dump @comps the first time and exit, it prints a bunch of "Attempt to free unreferenced scalar" messages but doesn't core dump. If I remove the Dumper line too, it works just fine.

    This is a problem both with perl and with Data::Dumper, and I suspect a bug report should go to both. 5.005* loathes references to undef and Dumper makes references to undef.

    local $_ = "0A72656B636148206C72655020726568746F6E41207473754A"; while(s/..$//) { print chr(hex($&)) }

Re: Core Dumping with Arrays
by ZZamboni (Curate) on Sep 08, 2000 at 19:11 UTC
    With 5.6 (on Solaris) I get the same results as gregorovius, and with 5.005_02 (also on Solaris) I get the same results as Corion. With 5.005_03 on OpenBSD 2.6 (x86) I get the following:
    (first dump omitted) Segmentation fault (core dumped)
    So it seems to be 5.005_03, all right. But I don't get any other messages. Just the core dump.

    --ZZamboni

(jcwren) Re: Core Dumping with Arrays
by jcwren (Prior) on Sep 08, 2000 at 19:23 UTC
    Interestingly enough (to me, at any rate...) I had this same problem the other day. chromatic and jlp were trying to help me out on it, and we never came to a successful resolution. I think I feel better knowing that at least *that* particular problem isn't some nastiness lying in wait because of my code.

    I'm always bothered by bugs that can't be explained, and that only show up under certain conditions (my code was running fine, *except* when I used Data::Dumper.) And, incidently, I'm running 5_005.03.

    --Chris

    e-mail jcwren
Re: Core Dumping with Arrays
by runrig (Abbot) on Sep 09, 2000 at 00:54 UTC
    In Data::Dumper::_dump(), if this:
    my($s, $val, $name) = @_;

    is changed to this:

    my $s = shift;
    my $val = shift;
    my $name = shift;

    then it all seems to work. It would be nice if the whole thing were rewritten to work with 'use strict'.
      You are right! Here is a patch:
      --- /usr/local/lib/perl5/5.00503/Data/Dumper.pm Fri May 28 18:34:02 19 +99 +++ Dumper.pm Fri Sep 8 19:55:37 2000 @@ -204,7 +204,9 @@ # and recurse, of course. # sub _dump { - my($s, $val, $name) = @_; + my $s = shift; + my $val = shift; + my $name = shift; my($sname); my($out, $realpack, $realtype, $type, $ipad, $id, $blesspad);
      In Perl 5.6.0 the code was not patched, instead they made this line work properly. Does anyone know the exact bug that is being tripped across here?
        I not sure if it has anything to do with it, but there is a bug where if perl tries to create an array of a certain range of very large sizes, it core dumps instead of a nice 'Out of memory' error. You can search p5p for 'pseudohash' because at first I thought it had to do with pseudo hash arrays, but later found it could happen with any array.