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

Hi all! Please may i request your valuable help. im trying to run this program below but says 'out of memory'. i have successfully executed scripts larger than this one, but im curious as to why this one is not working. Please can you tell me if there is an error in my code because of which there is 'out of memory'? thanks.
for ($i=0;$i<=(scalar(@blocks));$i++) { if($blocks[$index]=~m/^\d/) { my $a=0; if($dist[$b]>=0) { do { $dump[$a]=$dist[$b]; $sta[$a]=$start[$b]; $sto[$a]=$stop[$b]; $a++; $b++; $index++; } until($dist[$b]<0); $flag=(scalar(@dump)); my $e=0; my $d=$flag-1; if($flag==1) { print CLUSTER "$sta[$d]\t$sto[$d]\n"; print STA "$sta[$d]\n"; print STO "$sto[$d]\n"; } else { print CLUSTER "$sta[$e]\t$sto[$d]\n"; print STA "$sta[$e]\n"; print STO "$sto[$d]\n"; } splice(@dump); splice(@sta); splice(@sto); } else { print CLUSTER "$start[$b]\t$stop[$b]\n"; print STA "$start[$b]\n"; print STO "$stop[$b]\n"; $index++; $b++; } } else { print CLUSTER "$blocks[$index]\n"; $index++; } }

Replies are listed 'Best First'.
Re: out of memory!
by BrowserUk (Patriarch) on Jul 25, 2013 at 10:59 UTC

    Intriguing. You use $i here: for ($i=0;$i<=(scalar(@blocks));$i++)

    But then use $index here: if($blocks[$index]=~m/^\d/) ?

    i have successfully executed scripts larger than this one,

    It isn't the size of the script that counts; it is the size of the data.

    And as you haven't shown us how you are populating @blocks; nor told us how big that array is, there is nothing we can to to help you.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: out of memory!
by hdb (Monsignor) on Jul 25, 2013 at 10:54 UTC

    Are you running under use strict; use warnings;? Also, your line until($dist[$b]<0); makes me nervous. What if this condition is never true? Or $b exceeds the size of the array $dist?

Re: out of memory!
by kcott (Archbishop) on Jul 25, 2013 at 13:08 UTC

    G'day rocketperl,

    I see you've already received some good pointers; here's a few more.

    $a and $b are special variables: don't use them except for their intended purpose (see perlvar). Also, you've neither declared nor initialised $b.

    There's seven arrays that you use without declaring or initialising them: @blocks, @dist, @dump, @start, @sta, @stop, @sto. Furthermore, @sta and @sto are poorly named and could easily be confused with (or mistyped as or for) @start and @stop; as such, this represents many opportunities for potential errors.

    You have other variables that appear to leap into existence without declaration or initialisation (such as $flag and $index). strict will alert you to undeclared variables (except special ones like $b) and warnings may point out uninitialised variables (depending on context) as well as other potential problems (as ++hdb has already alluded to).

    do { ... } until (...); is a highly confusing construct in itself; regardless, in the context of the code you posted, it's completely unnecessary. Consider whether you think this is more readable and maintainable:

    if ($dist[$b] >= 0) { while ($dist[$b] >= 0) { ... }

    Your C-style for loop is overly complicated and prone to off-by-one errors. In fact, assuming you'd intended to use $i as an index for @blocks (see ++BrowserUk's comments on $i vs. $index), you do have an off-by-one error. Consider starting the loop as:

    for my $i (0 .. $#blocks) {

    You could probably write that even more succinctly as:

    for (@blocks) {

    but, without knowing exactly what's going with $i and $index, that may not be the case.

    -- Ken