Controllo allocazione dinamica

di il
11 risposte

Controllo allocazione dinamica

Salve a tutti
vorrei sapere se c'è qualche tecnica particolare per sapere se una variabile o una parte del vettore è stata allocata dinamicamente.
io per il momento ho usato questa ma credo che sia stralunata!

int* maxvtab = new int; if ( !maxvtab ){ n = 1; return -44; }
      int* maxhtab = new int; if ( !maxhtab ){ n = 2; return -44; }
      int* moda = new int; if ( !xtab ) { n = 3; return -44; }
      int* xtab = new int; if ( !ytab ) { n = 4; return -44; }
      int* ytab = new int; if ( !moda ) { n = 5; return -44; }
      bool* fridv = new bool; if( !fridv) { n = 6; return -44; }
      int* vtab = newint; if ( !vtab) { n = 7; return-44; }
      int* htab = newint; if ( !htab) { n = 8; return-44; }
al ritorno della funzione andrei a controllare il codice di ritorno e se c'è errore il valore di n.
e a seconda del valore andrei a deallocare tutte le variabili precedenti.
ma se sto allocando una matrice come potrei fare a deallocare tutte le righe e le colonne precedenti a quella che mi ha causato l'errore?
ringrazio anticipatamente tutti.

11 Risposte

  • Re: Controllo allocazione dinamica

    Quel codice è totalmente inefficace oltre che stralunato. Lo standard prevede che operator new lanci un'eccezione di tipo std::bad_alloc in caso l'allocazione fallisca, per cui affidarsi a un valore di ritorno (a proposito, il compilatore non da nemmeno un warning?)
    Affinché il tuo codice sia "efficace" dovresti fare:
    
    int* maxhtab = new int nothrow ; if ( !maxhtab ){ n = 2; return -44; }
    
    quel nothrow indica appunto di usare la versione di operator new che non lancia eccezioni, in alternativa puoi sempre usare std::malloc.
    A ogni modo se devi fare tutte quelle allocazioni di singoli int, c'è qualcosa che non va nel design generale. Che devi fare di preciso?

    Per quanto riguarda la funzione, esiste per visual c++ la _msize()
    https://msdn.microsoft.com/it-it/library/z2s077bc.asp
    che però è garantita solo per malloc, calloc e realloc. Non è detto che funzioni anche per new.
    Per gestire la memoria ti consiglio di dare un'occhiata a
    http://en.cppreference.com/w/cpp/memor
    in particolare gli smart pointer (unique_ptr etc.)
  • Re: Controllo allocazione dinamica

    Ciao
    parecchio che non ci si sente.
    tutti quegli int dichiarati dinamicamente servono al fine,tentativo, di ridurre i parametri passati alle funzioni che li utilizzano.
    lo scopo finale di tutto ciò e creare una modalità testuale per un compilatore.
    comunque il problema consiste nel deallocare tutte le variabili che erano state allocate nel caso in cui
    una variabile da allocare per un qualsiasi problema non riuscisse ad allocarsi.
    esempio:
    maxvtab allocazione ok
    maxhtab allocazione ok
    moda non si alloca per problemi
    in tal caso maxvtab e maxhtab dovrebbero essere deallocate per non lasciare aree occupate e inutilizzabili in memoria.
    qualche suggerimento?
  • Re: Controllo allocazione dinamica

    tutti quegli int dichiarati dinamicamente servono al fine,tentativo, di ridurre i parametri passati alle funzioni che li utilizzano.
    Se devi fare sette allocazioni pe sette variabili semplici, non vedo come pensi di ridurre i parametri in quel modo.

    Per quanto riguarda la gestione della memoria, usa unique_ptr. Il link della documentazione è nel post precedente.
    Nel C++ moderno ci si può dimenticare della gestione manuale della memoria (a parte casi limite).
  • Re: Controllo allocazione dinamica

    Scusami
    ma quando alloco dinamicamente una variabile, avendola sempre a disposizione, posso ometterla dalla lista dei parametri e comunque utilizzarla senza altri riferimenti oppure no?
  • Re: Controllo allocazione dinamica

    No, ti confondi con le variabili globali, che però non centrano niente con l'allocazione dinamica.
    Tra l'altro quando affermi
    ma quando alloco dinamicamente una variabile, avendola sempre a disposizione,
    è vero fintanto che a quella zona di memoria mantieni un riferimento (pointer). Perso il riferimento, persa la memoria. Ma in quel frammento di codice stai definendo delle variabili locali, per cui finita la funzione, addio variabili e memoria (che resta allocata e persa).
    Se vuoi ridurre il numero di parametri a una funzione (qualsiasi cosa tu intenda) usa una struct.
  • Re: Controllo allocazione dinamica

    So bene che le variabili globali non centrano con l'allocazione dinamica.
    infatti con le globali me le devo portare a presso tramite la direttiva extern!
    le variabili ad allocazione dinamica speravo che fossero simili alle vecchie variabili a locazione di memoria dell'assembler
    alle quali bastava una procedura di allocazione e nulla più.
    si potevano usare direttamente usando l'indirizzo e campavano, ben oltre il termine del programma, fin quando il programmatore non decideva di farle morire.
    usando una procedura di deallocazione.
    che tu sappia esiste in c++ una struttura che faccia la medesima cosa?
  • Re: Controllo allocazione dinamica

    In C/C++ è la stessa cosa.
    Supponiamo di avere qualcosa tipo:
    
    int* test() {
        int* var = new int;
        return var;
    }
    
    int* p = test();
    test();
    
    
    In entrambi i casi si effettua un'allocazione dinamica.
    Nel primo caso hai un riferimento all'indirizzo di memoria allocata che ti permette poi di manipolarla come vuoi; la puoi assegnare, deallocare etc.
    Nel secondo caso se non memorizzi l'indirizzo da qualche parte, perdi ogni possibilità di accesso alla memoria allocata, che rimane "viva" fino alla fine del programma.
  • Re: Controllo allocazione dinamica

    Beh sono simili ma molto meno potenti visto che c'è il rischio di perderle subito dopo la definizione.
    pero' a quseto punto sorge almeno 1 problema.
    che in ogni funzione dove la variabile viene usata comunque dovrebbe essere referenziata cosa che non porta molto vantaggio.
    per esempio:
    
    int test1;
    int*var=test()
    int* test() {
        int* var = new int;
        return var;
    }
    
    quindi se ho capito bene ammenoche non si definiscano array o matrici non conviene l'allocazione dinamica.
    P.S.
    l'ho definita bene questa matrice tridimensionale?
    int ***matvideo;
          int i,j,w; i = 0; j = 0; w = 0;
          matvideo = new int[maxvtab];
          for ( i = 0; i < maxvtab;i++)
             {
               *(maxvideo + 1) = new int[maxhtab];
             }
          for ( j = 0; j < maxhtab;j++)
             {
               *(maxvideo + 2) = new int[3];
             }
          for ( i = 0; i < maxvtab; i++ )
             {
               for ( j = 0; j < maxhtab; j++)
                  {
                    for ( w = 0; w < 3;w++)
                       {
                         matvideo[i] [j] [w] = -1;
                       }
                  }
             }
  • Re: Controllo allocazione dinamica

    smalldragon ha scritto:


    c'è il rischio di perderle subito dopo la definizione.
    ?

    Che vuoi dire?
    non porta molto vantaggio.
    Anche questo non lo capisco ...
    quindi se ho capito bene ammenoche non si definiscano array o matrici non conviene l'allocazione dinamica.
    L'allocazione dinamica si usa principalmente per allocare grandi quantità di dati (quindi per array) ma questo non ha nulla a che vedere con la "convenienza" dell'usare l'allocazione dinamica.
    l'ho definita bene questa matrice tridimensionale?
    Direi proprio di no ...
    
    int dimX, dimY, dimZ;
    int*** array;    
    
    e quindi
    
    array = new int**[dimX];
    for(int x = 0; x < dimX; ++x) 
    {
        array[x] = new int*[dimY];
    
        for(int y = 0; y < dimY; ++y) 
        {
            array[x][y] = new int[dimZ];
    
            for(int z = 0; z < dimZ; ++z)
            { 
                array[x][y][z] = 0;
            }
        }
    }
    
  • Re: Controllo allocazione dinamica

    Grazie per la correzione.

    oregon ha scritto:


    smalldragon ha scritto:
    c'è il rischio di perderle subito dopo la definizione.
    ?
    Che vuoi dire?
    volvo dire che se non mi faccio restituire l'indirizzo con la return o non mi copio il valore dell'indirizzo in una variabile referenziata, pur sapendo il nome, la varibile sarebbe inutilizzabile e quindi andrebbe persa con l'aggravante dei buchi di memoria.
    ergo non conviene molto visto che dovrei utilizzare comunque un riferimento globale per poterla usare.
    conviene solo per array multi dimensionali o strutture molto grandi per i quali si avrebbe un leggero aumento delle prestazioni.
    comunque
    il problema era nato dal fatto che io stavo cercando un sistema per definirmi una volta sola le variabili e non dovermele portare tramite riferimenti o extern "sempre a presso" in tutte le funzioni dove venivano utilizzate cosi da ridurre i parametri nelle funioni.
    per esempio:
    
    int testo(SDL_Windows **txtwin,SDL_Render **txtren,int &moda,int &wh,int &hh);
    int ristampa(TTF_Font* carattere,int grandezza,int matvideo[xx] [yy] [3],
                 SDL_Render *txtren,int moda,int maxvtab,int maxhtab);
    int visualizza(TTF_Font* carattere,SDL_Renderer* txtren,char* scritta,
                   int colo,int cola,int moda,int xtab,int ytab);
    
    essendoci variabili comuni tra le 3 funzioni volevo definirmi a parte queste ultime e poi utilizzarle liberamente all'interno delle funzioni.
    siccome in assembler c'era la possibilità di fare ciò credevo,sbagliando, che
    l'allocazione dinamica essendo molto simile a questa tecnica assembler pensavo di aver trovato la soluzione ma evidentemente mi sbagliavo.
  • Re: Controllo allocazione dinamica

    se non mi faccio restituire l'indirizzo con la return o non mi copio il valore dell'indirizzo in una variabile ...
    Questo è ovvio, ma se non fai queste cose vuol dire che non stai usando correttamente l'allocazione dinamica !
    ergo non conviene molto visto che dovrei utilizzare comunque un riferimento globale per poterla usare.
    Stai facendo confusione. La visibilità (globale/locale) non c'entra nulla con l'allocazione statica/dinamica. Sono concetti diversi.
    conviene solo per array multi dimensionali o strutture molto grandi per i quali si avrebbe un leggero aumento delle prestazioni.
    Non per le prestazioni ma perché hai la possibilità di usare l'heap e quindi ampie porzioni di memoria.
    
    int testo(SDL_Windows **txtwin,SDL_Render **txtren,int &moda,int &wh,int &hh);
    int ristampa(TTF_Font* carattere,int grandezza,int matvideo[xx] [yy] [3],
                 SDL_Render *txtren,int moda,int maxvtab,int maxhtab);
    int visualizza(TTF_Font* carattere,SDL_Renderer* txtren,char* scritta,
                   int colo,int cola,int moda,int xtab,int ytab);
    
    essendoci variabili comuni tra le 3 funzioni volevo definirmi a parte queste ultime e poi utilizzarle liberamente all'interno delle funzioni.
    Se non passi quei dati come parametri per ogni funzione allora devi utilizzare variabili globali, cosa che ti sconsiglio di fare, anche in assembler, in cui valgono le stesse regole.
    Se in assembler vuoi utilizzare delle variabili globali lo puoi fare come in C, ma puoi anche passare i puntatori nello stack per ogni funzione chiamata.
    siccome in assembler c'era la possibilità di fare ciò credevo
    In assembler non ci sono possibilità diverse da quelle del C (per evidenti motivi) e non so a cosa ti riferisci. Se non ne sei convinto perché ancora fai un po' di confusione tra i vari concetti, prova a scrivere i programmi in C e indicare al compilatore di generare l'equivalente testo assembler. Vedrai come si fa in assembler quello che si fa in C (e viceversa).
Devi accedere o registrarti per scrivere nel forum
11 risposte