Skip Menu |

This queue is for tickets about the Heap CPAN distribution.

Report information
The Basics
Id: 14410
Status: resolved
Priority: 0/
Queue: Heap

People
Owner: john [...] perlwolf.com
Requestors: chris [...] leishman.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.50
Fixed in: 0.71



Subject: Heap::Fibonacci::elem_DESTROY causes error during garbage collection
The elem_DESTROY sub (used during garbage collection) is subtly broken: sub elem_DESTROY { ... while( $el ) { $ch = $el->{child} and elem_DESTROY $ch; $next = $el->{right}; $el->{val}->heap(undef); $el->{child} = $el->{right} = $el->{left} = $el->{p} = $el->{val} = undef; $el = $next; } } The loop keeps walking to the right sibling around the fibonacci ring, and clearing destroying the children as well as clearing the heap reference, the data and the left and right references. However it will eventually reach the end of the ring and encounter itself again - and at this point the {val} will be undef and the call to $el->{val}->heap(undef) will fail. It probably should set $next conditionally, as in: $next = ($el->{right} != $el)? $el->{right} : undef; cheers, chris
The code that you omitted with the elipsis is significant. It contains the line: $el->{left}->{right} = undef; just before the while. That assignment breaks the circular loop of links, so that the while loop will never return to the original starting point. Instead, when it gets to the original last element, the value of $next will be set to undef and the while loop will terminate.
[JMM - Sun Sep 25 22:40:26 2005]: Show quoted text
> The code that you omitted with the elipsis is significant. It
contains Show quoted text
> the line: > > $el->{left}->{right} = undef; > > just before the while. That assignment breaks the circular loop of > links, so that the while loop will never return to the original > starting point. Instead, when it gets to the original last element, > the value of $next will be set to undef and the while loop will > terminate.
I just noticed that the original report was for version 0.50 - the code I descibed in my reply was added in version 0.71 to fix this issue.