?
Solved

Memory exhausted

Posted on 2005-05-13
7
Medium Priority
?
1,081 Views
Last Modified: 2011-09-20
Linux & HTTPD.
I'm testing the script below on a file of 4660 bytes and I'm getting the following HTTPD message:
Allowed memory size of 8388608 bytes exhausted (tried to allocate 3 bytes)

All I know is that the script reads the file and displays the length $fylel as 4660 bytes.

<?
$fyle=file_get_contents('../file5.txt.struct');
$fylel=strlen($fyle);
$outp="";
#
 for ($i=0; $i < $fylel; $i++) {#1
 if (substr($fyle,$i,1) != "&") {#2
  $outp .= (substr('$fyle',$i,1));
  }#2
   else {#3
   $cont=0;
   for ($j=$i; $j < $fylel; $j+6) {#4
    if (substr($fyle,$j,6) == "&nbsp;") {#5
     $cont++;
    }#5
    $outp .= "[" . chr($cont) . "]";
    $i=$j;
   }#4
  }#3
 }#1
?>

Questions:
There must be something in the code creating this situation, what is it?
Is it acceptable to change the value of $i = $j as above?
Any other hint most welcome.
0
Comment
Question by:rblampain
7 Comments
 
LVL 9

Expert Comment

by:AlanJDM
ID: 13997957
Lets start with what you are trying to do here. Strip ampersands(&) out of the file? Count spaces? There are easier ways to do these things.

Alan
0
 
LVL 3

Expert Comment

by:majestiq
ID: 13998912
I think your setting $i=$j is creating an infinite loop which is creating an infinitely long $outp string which is taking all of your memory.
0
 

Author Comment

by:rblampain
ID: 14001276
Thank you both.
The file is constituted of HTML tags separated by a variable number of &nbsp; (up to about 80), rendering it is not really important.
What I'm tryng to do is replace each series of contiguous &nbsp; instances with a user made tag around the number representing the number of contiguous &nbsp; between 2 HTML tags: example [37]
I'm using [ and ] to enclose the value and I'm using chr($cont) to represent the value as this uses only a single byte.

I think all the above should work, what I thought might not work is that each time an occurence of &nbsp; is found, the value of the index in the first for loop should be increased by 6 which is equal to giving the value of $j (from the second for loop) to $i (in the first for loop) and I know this doesn't work in some interpreters (like some BASIC in the old days).

If this is the case, perhaps you can advise a better way to code this that wouldn't create an infinite loop.  I do not have time to learn PHP by trial and errors and as soon as I hit a problem, I usually need help.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 49

Expert Comment

by:Roonaan
ID: 14001793
rblampain, you wouldn't want to use [ chr($cont) ], because possibly somehow sometime there might be a string longer than 255 repeating elements of &nbsp; (although this offcourse can be tested using conditional statements).

However, a possible working code example which looks somewhat more simpeler than yours would be:

<?php

//this string has to be magically turned into <tag>[4]</tag><tag>2</tag>
$string = '<tag>&nbsp;&nbsp;&nbsp;&nbsp;</tag><tag>&nbsp;&nbsp;</tag>';

$token = '&nbsp;';
$toklen = strlen($token);

while(false !== ($start = strpos($string, $token))) //detect the occurence of '&nbsp;'
{
  $left = substr($string,0, $start);
  $string = substr($string,$start);
  $tokens = 0;
  while(substr($string,0,$toklen) == $token)
  {
    $tokens++;
    $string = substr($string, $toklen);
  }
  $string = $left.'['.$tokens.']'.$string;
}

echo htmlspecialchars($string);
?>

-r-
0
 
LVL 49

Expert Comment

by:Roonaan
ID: 14001804
You could even try this:

$string = preg_replace('/(&nbsp;)+/e', '"[".(count(explode("$token","\\0"))-1)."]"', $string);

-r-
0
 
LVL 49

Accepted Solution

by:
Roonaan earned 2000 total points
ID: 14001807
Full code for the last post:

<?php

//this string has to be magically turned into <tag>[4]</tag><tag>2</tag>
$string = '<tag>&nbsp;&nbsp;&nbsp;&nbsp;</tag><tag>&nbsp;&nbsp;</tag>';

$token = '&nbsp;';
$string = preg_replace('/('.$token.')+/e', '"[".(count(explode("$token","\\0"))-1)."]"', $string);
echo htmlspecialchars($string).'<br/>';
?>

-r-
0
 

Author Comment

by:rblampain
ID: 14004678
To majestiq:
it seems my code was in trouble before reaching that line

To Roonan:
a single line of code - and it works - I'll need a few days to believe it.
No doubt you deserve the points.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to count occurrences of each item in an array.
Suggested Courses
Course of the Month15 days, 15 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question