Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it L'avatar di leonix
    Registrato dal
    Jul 2005
    Messaggi
    18

    Fatal error: memoria allocata esaurita

    Un errore curioso mi sta facendo impazzire:
    Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 8388608 bytes) in /home/mhd-01/www.pizza-flash.it/htdocs/stuff/sumDoubleItems.php on line 18
    a prescindere dal fatto che 8388608 bytes sono meno di 67108864, e giá per questo non capisco come si possa creare un errore simile, ma il codice che sto eseguendo é veramente molto molto semplice, e non capisco dove sta l'errore. Forse sono stato troppe ore davanti allo schermo e non vedo un ; o un $ mancante....
    Ho cercato su google e tra gli altri che ho trovato che avevano il mio stesso problema, non sono riuscito a trovare chi l'abbia risolto, solo conversazioni lunghissime con domande su quante persone navigassero contemporaneamente sui loro forum, o su che versione di software vari stavano utilizzando.
    Ho provato a inserire
    codice:
    ini_set('memory_limit', '16M');
    come da diverse parti si consiglia, ma il risultato é stato ancora piú assurdo:
    Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 32 bytes) in /home/mhd-01/www.pizza-flash.it/htdocs/stuff/sumDoubleItems.php on line 5
    La funzione e la classe presenti in questo file che vi allego servono per smaltire le informazioni ridondanti in un cookie contenente oggetti di un carrello elettronico, salvati nella forma NUMEROx:NUMERO#; dove i due numeri rappresentano quantitá e id dell'oggetto.
    Quando un utente scegliesse due volte lo stesso oggetto si produrrebbero due semistringhe riferenti allo stesso id, e con il mio codice sto cercando di sommare le quantitá e riprodurre la stessa stringa di partenza senza ripetizioni di id.
    codice:
    <?php
    class order_from_string{
      public function __construct($order_str){
        $temp=explode(":", $order_str);
    
    // le due seguenti espressioni estrapolano ID e QUANTITA dalla stringa del cookie in cui le informazioni sono salvate secondo la forma QUANTITA_1x:ID_1#;QUANTITA_2x:ID_2#;QUANTITA_3x:ID_3#;...ecc
        $this->amount=substr($temp[0],0,(strlen($temp[0])-1));
    	$this->id=substr($temp[1],0,(strlen($temp[1])-1));
     }
      public $amount=0;
      public $id=0;
    }
    
    function sumDoubleItems($cookie_string){
    	ini_set('memory_limit', '16M');        // riga aggiunta senza risultati apparenti
    	$returnString="";
    	$order_raw=explode(";", $cookie_string);
    	$order=Array();
    
    	for($i=0; i<count($order_raw); $i++){
    		$order[$i]=new order_from_string($order_raw[$i]);
    	}
    
    	for($i=0; $i<count($order); $i++){
    		for($j=0; $j<count($order); $j++){
    			if($i!=$j && $order[$i]->id==$order[$j]->id){
    				$tempAmount=$order[$i]->amount+$order[$j]->amount;
    				$order[$i]->amount=$tempAmount;
    				unset($order[$j]);
    				$order=array_values($order);
    			}
    		}
    	}
    
    	foreach($order as $o)
    		$returnString.=$o->amount."x:".$o->id."#;";
    
    	return returnString;
    }
    
    ?>
    aggiungo per completezza che la funzione sumDoubleItems() é chiamata nel seguente modo
    codice:
    $sumDoubleItems($_COOKIE['cart_content']);
    dove il cookie potrebbe contenere ad esempio la seguente stringa
    codice:
    1x:3#;12x:3#;44x:1#;33x:3#;
    e l'obiettivo sarebbe precisamente di ottenere come output la seguente stringa da salvare nuovamente nel cookie
    codice:
    46x:3#;44x:1#;
    Oggi con un po piu di lucidita ho riscritto un programma che emula le funzioni di questo qua sopra semplificandolo, e stranamente funziona alla perfezione!!! non riesco a trovare le differenze,... ecco il nuovo

    codice:
    <?php
    
    
    setcookie("cart_content", "1x:3#;3x:3#;4x:3#;5x:9#;4x:2#;1x:3#;3x:3#;4x:3#;5x:9#;4x:2#;", time()+3600);
    
    echo $_COOKIE["cart_content"];
    
    // anziche utilizzare la classe order_from_string qui i valori vengono salvati in due array
    $ids=Array();    // uno per gli ID
    $ams=Array();  // uno per le QUANTITA
    
    $raw=explode(";", $_COOKIE["cart_content"]);
    
    for($k=0; $k<count($raw); $k++){
        $temp=explode(":", $raw[$k]);
        $ams[$k]=substr($temp[0],0,(strlen($temp[0])-1));
        $ids[$k]=substr($temp[1],0,(strlen($temp[1])-1));
        unset($temp);
    }
    
    
    	for($i=0; $i<count($raw); $i++){
    		for($j=0; $j<count($raw); $j++){
    			if($i!=$j && $ids[$i]==$ids[$j]){
    				$tempAmount=$ams[$i]+$ams[$j];
    				$ams[$i]=$tempAmount;
    				unset($ids[$j]);
    				unset($ams[$j]);
    				$ids=array_values($ids);
    				$ams=array_values($ams);
    				unset($tempAmount);
    			}
    		}
    	}
    echo "
    
    ";
    for($i=0; $i<count($ids); $i++)
    	echo $ams[$i]."x:".$ids[$i]."#;"
    ?>
    output corretto di questo altro programma
    1x:3#;3x:3#;4x:3#;5x:9#;4x:2#;1x:3#;3x:3#;4x:3#;5x :9#;4x:2#; // echo $_COOKIE['cart_content']

    10x:9#;8x:2#;16x:3#; // output della stringa corretta che dovrebbe essere salvata nel cookie

  2. #2
    L'errore è coerente. Quello che ti dice il primo errore è che hai esaurito i 64MB di memoria che concedi agli script, e che stava tentando di allocare "ulteriori" 8 Mb.
    Abbassare il limite a 16MB ovviamente peggiora le cose e il programma si blocca ben prima!

    Dov'è il problema? Vedendo solo questa classe è strano che un ciclo richieda così tanta memoria, ma probabilmente sei già al limite con tutto il precedente codice, ovvero prima di chiamare la funzione.

    Se hai a disposizione un debugger, esegui una profilazione e trova la funzione o la classe che utilizza più memoria. Controllala (forse lasci "aperte" troppe risorse, per esempio esegui molte query senza poi scartarne i risultati, liberando le risorse, o usi degli array grossi istanziati con classi) e cerca di diminuirne l'impatto sulla ram.


  3. #3
    L'errore e' in questa riga:
    codice:
    	for($i=0; i<count($order_raw); $i++){
    manca il $ prima della "i" il che fa si che PHP usi la stringa "i" invece del valore di $i rendendo il ciclo infinito, da cui il consumo di tutta la memoria.

    Suggerisco un'implementazione alternativa, un po' piu' PHP che non e' il C e mette a disposizione anche altre cose oltre al semplice ciclo for

    codice:
    <?php
    
    $string = "1x:3#;3x:3#;4x:3#;5x:9#;4x:2#;1x:3#;3x:3#;4x:3#;5x:9#;4x:2#;";
    
    echo sum_values($string);
    
    function sum_values($string) {
        $data = array();
    
        foreach ( explode(';', $string) as $part ) {
            if ( preg_match('/(\d+)x:(\d+)#/', $part, $match) ) {
                if ( isset($data[$match[2]]) ) {
                    $data[$match[2]] += $match[1];
                } else {
                    $data[$match[2]] = $match[1];
                }
            }
        }
    
        $output = array();
    
        foreach ( $data as $key => $value ) {
            $output[] = "{$value}x:{$key}";
        }
    
        $string = implode(';', $output);
    
        return $string;
    }

  4. #4
    Originariamente inviato da k.b
    L'errore e' in questa riga:
    codice:
    	for($i=0; i<count($order_raw); $i++){
    manca il $ prima della "i"
    Orca, non me n'ero accorto

  5. #5
    A occhio nemmeno io, ma e' bastato far girare quel codice da riga di comando con la visualizzazione di errori e warning attiva per vedere questo:
    codice:
    PHP Notice:  Use of undefined constant i - assumed 'i' in /var/www/prove/foo.php on line 20

  6. #6
    Utente di HTML.it L'avatar di Secta
    Registrato dal
    May 2002
    Messaggi
    365
    Originariamente inviato da Dascos
    Orca, non me n'ero accorto
    Le cose sono 3 (vedi il post sul require):

    1) k.b non ha bevuto nulla tra ieri e oggi;
    2) k.b ha la vista da falco;
    3) k.b ha prestato + attenzione di noi;

    Io sono indeciso tra 1 e 2, la 3 tenderei ad escluderla
    "Dai diamanti non nasce niente, dal letame nascon fiori."
    Fabrizio De Andrè

  7. #7
    Utente di HTML.it L'avatar di leonix
    Registrato dal
    Jul 2005
    Messaggi
    18
    aaaah finalmente... -_-

    grazie 1000!!!

    grazie anche per il suggerimento di implementazione alternativa, devo informarmi un po' meglio su queste benedette regular expression perché ho gia avuto esperienza in passato di come possano semplificare estremamente il lavoro...

    alla prossima

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.