Memoria dinamica C ++

Una buona comprensione di come funziona realmente la memoria dinamica in C ++ è essenziale per diventare un buon programmatore C ++. La memoria nel tuo programma C ++ è divisa in due parti:

  • The stack - Tutte le variabili dichiarate all'interno della funzione occuperanno memoria dallo stack.

  • The heap - Questa è la memoria inutilizzata del programma e può essere utilizzata per allocare la memoria dinamicamente durante l'esecuzione del programma.

Molte volte, non si è a conoscenza in anticipo di quanta memoria sarà necessaria per memorizzare informazioni particolari in una variabile definita e la dimensione della memoria richiesta può essere determinata in fase di esecuzione.

È possibile allocare memoria in fase di esecuzione all'interno dell'heap per la variabile di un determinato tipo utilizzando un operatore speciale in C ++ che restituisce l'indirizzo dello spazio allocato. Questo operatore è chiamatonew operatore.

Se non hai più bisogno di memoria allocata dinamicamente, puoi usare delete operatore, che disalloca la memoria precedentemente allocata dal nuovo operatore.

nuovo ed elimina operatori

C'è la seguente sintassi generica da usare new operatore per allocare la memoria dinamicamente per qualsiasi tipo di dati.

new data-type;

Qui, data-typepotrebbe essere qualsiasi tipo di dati incorporato, incluso un array, o qualsiasi tipo di dati definito dall'utente che include classe o struttura. Cominciamo con i tipi di dati incorporati. Ad esempio possiamo definire un puntatore al tipo double e quindi richiedere che la memoria venga allocata in fase di esecuzione. Possiamo farlo usando ilnew operatore con le seguenti istruzioni:

double* pvalue  = NULL; // Pointer initialized with null
pvalue  = new double;   // Request memory for the variable

La memoria potrebbe non essere stata allocata correttamente, se l'archivio gratuito era stato utilizzato. Quindi è buona norma controllare se il nuovo operatore sta restituendo il puntatore NULL e intraprendere l'azione appropriata come di seguito:

double* pvalue  = NULL;
if( !(pvalue  = new double )) {
   cout << "Error: out of memory." <<endl;
   exit(1);
}

Il malloc()funzione da C, esiste ancora in C ++, ma si consiglia di evitare di utilizzare la funzione malloc (). Il vantaggio principale di new rispetto a malloc () è che new non si limita ad allocare memoria, ma costruisce oggetti che è lo scopo principale di C ++.

In qualsiasi momento, quando senti che una variabile che è stata allocata dinamicamente non è più necessaria, puoi liberare la memoria che occupa nella memoria libera con l'operatore 'cancella' come segue:

delete pvalue;        // Release memory pointed to by pvalue

Mettiamo i concetti sopra e formiamo il seguente esempio per mostrare come funzionano 'nuovo' e 'cancella' -

#include <iostream>
using namespace std;

int main () {
   double* pvalue  = NULL; // Pointer initialized with null
   pvalue  = new double;   // Request memory for the variable
 
   *pvalue = 29494.99;     // Store value at allocated address
   cout << "Value of pvalue : " << *pvalue << endl;

   delete pvalue;         // free up the memory.

   return 0;
}

Se compiliamo ed eseguiamo il codice sopra, questo produrrebbe il seguente risultato:

Value of pvalue : 29495

Allocazione dinamica della memoria per array

Considera di voler allocare memoria per un array di caratteri, cioè una stringa di 20 caratteri. Usando la stessa sintassi che abbiamo usato sopra possiamo allocare la memoria dinamicamente come mostrato di seguito.

char* pvalue  = NULL;         // Pointer initialized with null
pvalue  = new char[20];       // Request memory for the variable

Per rimuovere l'array che abbiamo appena creato, l'istruzione sarebbe simile a questa:

delete [] pvalue;             // Delete array pointed to by pvalue

Seguendo la sintassi generica simile di new operator, puoi allocare un array multidimensionale come segue:

double** pvalue  = NULL;      // Pointer initialized with null 
pvalue  = new double [3][4];  // Allocate memory for a 3x4 array

Tuttavia, la sintassi per liberare la memoria per array multidimensionali rimarrà comunque la stessa di cui sopra -

delete [] pvalue;            // Delete array pointed to by pvalue

Allocazione dinamica della memoria per gli oggetti

Gli oggetti non sono diversi dai tipi di dati semplici. Ad esempio, considera il codice seguente in cui utilizzeremo un array di oggetti per chiarire il concetto:

#include <iostream>
using namespace std;

class Box {
   public:
      Box() { 
         cout << "Constructor called!" <<endl; 
      }
      ~Box() { 
         cout << "Destructor called!" <<endl; 
      }
};
int main() {
   Box* myBoxArray = new Box[4];
   delete [] myBoxArray; // Delete array

   return 0;
}

Se dovessi allocare un array di quattro oggetti Box, il costruttore Simple verrebbe chiamato quattro volte e in modo simile durante l'eliminazione di questi oggetti, anche il distruttore verrà chiamato lo stesso numero di volte.

Se compiliamo ed eseguiamo il codice sopra, questo produrrebbe il seguente risultato:

Constructor called!
Constructor called!
Constructor called!
Constructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!