Esiste ancora un'altra possibilità per inizializzare una variabile puntatore: utilizzando l'operatore new messo a disposizione dal C++.
Quando si scrive:
codice:
int x = 20;
int* p_x = NULL;
......
......
p_x = new int;
*p_x = x;
quello che si ottiene è un risultato apparentemente simile a quello visto negli esempi precedenti, ma in realtà abbastanza diverso.
L'istruzione:
altro non fa che allocare una quantità di memoria necessaria per contenere un int (ovvero 2 byte) ed assegnare l'indirizzo del primo byte di memoria alla variabile p_x. Questo indirizzo è certamente diverso da quello in cui è contenuta la variabile x stessa, per cui in tal caso avremo in realtà due variabili intere differenti che contengono lo stesso valore.
E' anche possibile usare l'istruzione:
codice:
p_x = new int(20);
per inizializzare direttamente il valore *p_x a 20.
Si faccia ora attenzione. Abbiamo detto che le variabili puntatore fanno riferimento alla memoria dinamica (heap). Diversamente dalla memoria statica, tutte le variabili puntatore allocate dal programmatore devono essere poi distrutte quando non servono più, per evitare i cosìdetti "memory leaks", ovvero per evitare che la memoria allocata resti tale anche dopo la terminazione del programma.
L'istruzione del C++ che serve per distruggere una variabile puntatore è: delete.
Nel caso dell'esempio precedente, avremmo:
codice:
int x = 20;
int* p_x = NULL;
......
......
p_x = new int;
*p_x = x;
......
......
delete p_x;
// La variabile p_x non serve più. Possiamo deallocarla
......
......
Per capire cosa è un memory leak, vediamo l'esempio seguente:
codice:
int x = 20;
int* p_x = NULL;
......
......
p_x = new int;
p_x = & x; // Attenzione!! Memory leak!!
*p_x = 20;
......
Perchè quando si esegue l'istruzione p_x = new int si sta creando un memory leak? La risposta è semplice. La variabile p_x è stata innanzitutto inizializzata utilizzando l'istruzione p_x = new int.
Tale istruzione ha fatto sì che venissero allocati due byte ed assegnato l'indirizzo del primo di questi byte alla variabile p_x. Quando poi si esegue l'istruzione p_x = & x la variabile p_x viene fatta puntare all'indirizzo in cui è contenuta la variabile x ma in nessun modo viene deallocata la memoria che era stata allocata in precedenza. Questo causa il famoso memory leak.
Bisogna stare molto attenti ai memory leak. Spesso non sono semplici da riconoscere e possono causare problemi ai programmi causando una graduale diminuzione delle risorse di sistema.
Per evitare il memory leak di prima avremmo dovuto scrivere:
codice:
int x = 20;
int* p_x = NULL;
......
......
p_x = new int;
delete p_x; // Deallocazione della memoria allocata da p_x
p_x = & x; // Corretto!
*p_x = 20;
......