Visualizzazione dei risultati da 1 a 10 su 10

Discussione: [c++] problema memoria

  1. #1
    Utente di HTML.it L'avatar di mamo139
    Registrato dal
    May 2005
    residenza
    Londra
    Messaggi
    841

    [c++] problema memoria

    è un problema che mi era capitato per lo stesso motivo e lo avevamo risolto in un topic precedente, ma in questo nuovo codice si ripresenta di nuovo: la riga in grossetto e i due array col e col2 accrescono l'utilizzo di ram ad ogni ciclo e non so come pulirle...

    grazie di nuovo
    codice:
    //----------------------------------------------------------------------------- 
    #include "ppm_image.h" 
    #include <complex> 
    #include <math.h> 
    #include <windows.h> 
    //----------------------------------------------------------------------------- 
    using namespace std; 
    //----------------------------------------------------------------------------- 
    
    #define WIDTH  10000
    #define HEIGHT 10000
    
                     #define Y1 2
    #define X0 -2
                                     #define X1 2
                     #define Y0 -2
    
    #define julia1 -0.7268953
    #define julia2 0.18888
    
    #define DEPTH 4000
    
    unsigned int * hsv_rgb(unsigned int *);
    
    int main() 
       { 
       complex<double> value, point, julia; 
       julia = complex<double>(julia1,julia2);
       double r, i, modulo; 
       long cnt; 
       
       //dati utili per colorare
       long cnt_tot=0, media_cnt=0, media_cnt_n=0, c_cnt=0;
       unsigned int *col;
       col = new unsigned int[3]; col[0]=0;col[1]=0;col[2]=0;
       unsigned int *col2;
       col2 = new unsigned int[3]; col2[0]=0;col2[1]=0;col2[2]=0;  
        
       // Creo un'immagine vuota di dimensione WIDTH*HEIGHT 
       PpmImage img(WIDTH, HEIGHT); 
    
       for(int x=0; x<WIDTH; x++){ 
          r = X0+((double(x)*(X1-X0))/double(WIDTH));       
          for(int y=0; y<HEIGHT; y++){ 
             i = Y0+((double(y)*(Y1-Y0))/double(HEIGHT)); 
             
             point = complex<double>(r,i); 
             value = point; 
              
             // iniziamo il ciclo 
             for(cnt=0; cnt<DEPTH; cnt++){ 
                value = value*value+julia; 
                modulo = abs(value); 
                if(modulo>2)break; 
             } 
                 
             if(modulo<=2){ 
                img.SetPixel(x,y,0,0,0); 
             } 
             else{ 
                // invece di disegnare un pixel bianco ne disegno uno colorato che dipende da cnt 
                unsigned int red, green, blue; //colore, contrasto, luminosità
                
                cnt_tot=cnt_tot+cnt;
                media_cnt_n++;
                c_cnt = cnt;
                
                red   = (c_cnt)%360; 
                green = 250; 
                blue  = 250;   
    
                if(red>359)   red=359; 
                if(green>255) green=255; 
                if(blue>255)  blue=255; 
                
                col[0]=red;
                col[1]=green;
                col[2]=blue;
    
                col2 = hsv_rgb(col); 
    
                img.SetPixel(x, y, col2[0], col2[1], col2[2]); 
    
             } 
          } 
          printf("%d\n",x);
       } 
    
       // Salvo l'immagine 
       img.SaveToFile("mandelbrot.ppm"); 
       
       media_cnt=cnt_tot/media_cnt_n;
       printf("cnt medio: %d\n",media_cnt);
       system("pause");
       return 0;
    }
    
    unsigned int * hsv_rgb(unsigned int hsv[3]){
             
        //printf("REVERSE:\nH:%d\nS:%d\nV:%d\n",hsv[0],hsv[1],hsv[2]);          
        double *dRGB;
        dRGB = new double[3];    
        
        double H = ((double)hsv[0]);
        double S = ((double)hsv[1])/255;
        double V = ((double)hsv[2])/255;
        
        double hi = ((int)(H/60))%6;
        double f = (H/60) - (double)hi;
        double p = V*(1-S);
        double q = V*(1-(f*S));
        double t = V*(1-(1-f)*S);
        
        if (hi == 0){ dRGB[0]=V;dRGB[1]=t;dRGB[2]=p;}
        else if (hi == 1){ dRGB[0]=q;dRGB[1]=V;dRGB[2]=p;}
        else if (hi == 2){ dRGB[0]=p;dRGB[1]=V;dRGB[2]=t;}
        else if (hi == 3){ dRGB[0]=p;dRGB[1]=q;dRGB[2]=V;}
        else if (hi == 4){ dRGB[0]=t;dRGB[1]=p;dRGB[2]=V;}
        else if (hi == 5){ dRGB[0]=V;dRGB[1]=p;dRGB[2]=q;}
        else printf("ERRORE!");
    
        //printf("R:%f\nG:%f\nB:%f\n",dRGB[0],dRGB[1],dRGB[2]);
        
        unsigned int *RGB;
        RGB = new unsigned int[3];    
        
        RGB[0] = (int)(dRGB[0]*255);
        RGB[1] = (int)(dRGB[1]*255);
        RGB[2] = (int)(dRGB[2]*255);
        
        free(dRGB); 
        
        //printf("R:%d\nG:%d\nB:%d\n",RGB[0],RGB[1],RGB[2]);  
        return RGB;   
    }

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    1) Non mischiare new e free (usa new e delete)

    2) Ci deve essere una delete per ogni new

    Controlla che in tutto il codice queste due regole siano SEMPRE rispettate ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304

    Moderazione

    Invece di utilizzare il pulsante "Quote" per scrivere il codice utilizza il pulsante "#".
    Se preferisci scrivere i tag a mano, usa [code] e [/code] al posto di [quote] e [/quote].

    Il tuo post l'ho sistemato io.

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  4. #4
    Utente di HTML.it L'avatar di mamo139
    Registrato dal
    May 2005
    residenza
    Londra
    Messaggi
    841
    Originariamente inviato da oregon
    1) Non mischiare new e free (usa new e delete)

    2) Ci deve essere una delete per ogni new

    Controlla che in tutto il codice queste due regole siano SEMPRE rispettate ...
    dunque... ho sistemato il codice così rispettando le tue regole, ma la memoria utilizzata continua comunque a salire fino a fine programma...
    codice:
    //----------------------------------------------------------------------------- 
    #include "ppm_image.h" 
    #include <complex> 
    #include <math.h> 
    #include <windows.h> 
    //----------------------------------------------------------------------------- 
    using namespace std; 
    //----------------------------------------------------------------------------- 
    
    #define WIDTH  10000
    #define HEIGHT 10000
    
                     #define Y1 2
    #define X0 -2
                                     #define X1 2
                     #define Y0 -2
    
    #define julia1 -0.7268953
    #define julia2 0.18888
    
    #define DEPTH 4000
    
    unsigned int * hsv_rgb(unsigned int *);
    
    int main() 
       { 
       complex<double> value, point, julia; 
       julia = complex<double>(julia1,julia2);
       double r, i, modulo; 
       long cnt; 
       
       //dati utili per colorare
       long cnt_tot=0, media_cnt=0, media_cnt_n=0, c_cnt=0;
    
        
       // Creo un'immagine vuota di dimensione WIDTH*HEIGHT 
       PpmImage img(WIDTH, HEIGHT); 
    
       for(int x=0; x<WIDTH; x++){ 
          r = X0+((double(x)*(X1-X0))/double(WIDTH));       
          for(int y=0; y<HEIGHT; y++){ 
             i = Y0+((double(y)*(Y1-Y0))/double(HEIGHT)); 
             
             point = complex<double>(r,i); 
             value = point; 
              
             // iniziamo il ciclo 
             for(cnt=0; cnt<DEPTH; cnt++){ 
                value = value*value+julia; 
                modulo = abs(value); 
                if(modulo>2)break; 
             } 
                 
             if(modulo<=2){ 
                img.SetPixel(x,y,0,0,0); 
             } 
             else{ 
                // invece di disegnare un pixel bianco ne disegno uno colorato che dipende da cnt 
                unsigned int red, green, blue; //colore, contrasto, luminosità
                   
                unsigned int *col;
                col = new unsigned int[3]; 
                unsigned int *col2;
                col2 = new unsigned int[3]; 
                cnt_tot=cnt_tot+cnt;
                media_cnt_n++;
                c_cnt = cnt;
                
                red   = (c_cnt)%360; 
                green = 250; 
                blue  = 250;   
    
                if(red>359)   red=359; 
                if(green>255) green=255; 
                if(blue>255)  blue=255; 
                
                col[0]=red;
                col[1]=green;
                col[2]=blue;
    
                col2 = hsv_rgb(col);
                delete(col);
    
                img.SetPixel(x, y, col2[0], col2[1], col2[2]); 
                delete(col2);
             } 
          } 
          printf("%d\n",x);
       } 
    
       // Salvo l'immagine 
       img.SaveToFile("mandelbrot.ppm"); 
       
       media_cnt=cnt_tot/media_cnt_n;
       printf("cnt medio: %d\n",media_cnt);
       system("pause");
       return 0;
    }
    
    
    
    
    
    
    
    
    
    unsigned int * hsv_rgb(unsigned int hsv[3]){
             
        //printf("REVERSE:\nH:%d\nS:%d\nV:%d\n",hsv[0],hsv[1],hsv[2]);          
        double *dRGB;
        dRGB = new double[3];    
        
        double H = ((double)hsv[0]);
        double S = ((double)hsv[1])/255;
        double V = ((double)hsv[2])/255;
        
        double hi = ((int)(H/60))%6;
        double f = (H/60) - (double)hi;
        double p = V*(1-S);
        double q = V*(1-(f*S));
        double t = V*(1-(1-f)*S);
        
        if (hi == 0){ dRGB[0]=V;dRGB[1]=t;dRGB[2]=p;}
        else if (hi == 1){ dRGB[0]=q;dRGB[1]=V;dRGB[2]=p;}
        else if (hi == 2){ dRGB[0]=p;dRGB[1]=V;dRGB[2]=t;}
        else if (hi == 3){ dRGB[0]=p;dRGB[1]=q;dRGB[2]=V;}
        else if (hi == 4){ dRGB[0]=t;dRGB[1]=p;dRGB[2]=V;}
        else if (hi == 5){ dRGB[0]=V;dRGB[1]=p;dRGB[2]=q;}
        else printf("ERRORE!");
    
        //printf("R:%f\nG:%f\nB:%f\n",dRGB[0],dRGB[1],dRGB[2]);
        
        unsigned int *RGB;
        RGB = new unsigned int[3];    
        
        RGB[0] = (int)(dRGB[0]*255);
        RGB[1] = (int)(dRGB[1]*255);
        RGB[2] = (int)(dRGB[2]*255);
        
        delete(dRGB); 
        
        //printf("R:%d\nG:%d\nB:%d\n",RGB[0],RGB[1],RGB[2]);  
        return RGB;   
    }
    Originariamente inviato da LeleFT
    Invece di utilizzare il pulsante "Quote" per scrivere il codice utilizza il pulsante "#".
    Se preferisci scrivere i tag a mano, usa [code] e [/code] al posto di [quote] e [/quote].

    Il tuo post l'ho sistemato io.

    Ciao.
    grazie

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Di questa allocazione

    col = new unsigned int[3];

    non c'e' la delete ... anzi, non vedo perche' farla questa allocazione.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Tra l'altro se allochi un array con new [], devi fare la deallocazione con delete []

    Quindi non delete(col2) ma delete [] col2

  7. #7
    Codice PHP:
    col2 hsv_rgb(col); 
    sovrascrive il valore di col2 precedentemente allocato con

    Codice PHP:
    col2 = new unsigned int[3]; 
    Rinomina hsv_rgb in:

    Codice PHP:
    NewArrayHsvFromRgb 
    in modo da enfatizzare che restituisca un puntatore ad array da liberare a cura del chiamante.

    Elimina
    Codice PHP:
    col2 = new unsigned int[3]; 
    e per liberare gli array (quelli allocati con "new double [3]"):

    Codice PHP:
    delete [] arrayDaLiberare

  8. #8
    Utente di HTML.it L'avatar di mamo139
    Registrato dal
    May 2005
    residenza
    Londra
    Messaggi
    841
    problema risolto, grazie mille a tutti

    comunque per ricapitolare: new lo uso sostanzialmente sei i dati li passo io (ad esempio col[0]=red mentre invece non devo usarlo quando i dati li passa tutti una funzione (ad esempio col2=miafunzione() poi dopo aver usato le variabili le cancello con un delete[]variabile...

    grazie ancora

  9. #9
    Originariamente inviato da mamo139
    problema risolto, grazie mille a tutti

    comunque per ricapitolare: new lo uso sostanzialmente sei i dati li passo io (ad esempio col[0]=red mentre invece non devo usarlo quando i dati li passa tutti una funzione (ad esempio col2=miafunzione() poi dopo aver usato le variabili le cancello con un delete[]variabile...

    grazie ancora
    Come ti ho già accennato prima, inventati delle convenzioni che ti permettano di individuare al volo se una funzione restituisce puntatori da liberare a cura del chiamante: ad esempio premetti al nome della funzione "New" per oggetti che devono essere liberati con delete, e "NewArray" per oggetti che devono essere liberati con delete [].

    quindi nel tuo esempio:
    Codice PHP:
    col2 NewArrayMiaFunzione (); 

  10. #10
    Utente di HTML.it L'avatar di mamo139
    Registrato dal
    May 2005
    residenza
    Londra
    Messaggi
    841
    capito


    dunque, per chi è interessato ecco l'output del codice, anche se in qualità molto scadente
    (il file originale è di 300.000mb in formato bmp ed è bellissimo perche ci si puo zoomare dentro e vedere che la figura prosegue in figure sempre piu piccole)


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 © 2024 vBulletin Solutions, Inc. All rights reserved.