inizializzazione di una variabile puntatore

17 marzo 2006

Anche per le variabili puntatore esiste la possibilità di ricorrere all’inizializzazione nel momento della loro definizione. Ad esempio:

int x;
int* p_x = & x;
char c ;
char* p_c = & c;

Il C++ mette a disposizione un tipo particolare di inizializzazione di un puntatore. Infatti è possibile, ed anzi è buona norma farlo, inizializzare una variabile puntatore a NULL (ovvero non la si fa puntare a nessun indirizzo di memoria) .
Ad esempio:

int* p_x = NULL;
char* p_c = NULL;

Quando però si inizializza un puntatore a NULL, si deve tener presente che non è possible in alcun modo utilizzare la variabile puntatore per nessuna operazione finchè non la si inizializzi con un indirizzo valido.
Infatti, se provassimo a scrivere:

int* p_x = NULL;
cout << *p_x << endl;
// Errore!!

otterremmo un errore in esecuzione in quanto la variabile puntatore p_x non punta nessuna variabile intera che contenga un valore valido.
Occorrerà far puntare p_x ad una variabile intera:

int x = 20;
int* p_x = NULL;
……
……
……
p_x = & x;
cout << *p_x << endl;
// Adesso è corretto

Esiste ancora un’altra possibilità per inizializzare una variabile puntatore: utilizzando l’operatore new messo a disposizione dal C++.
Quando si scrive:

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:

p_x = new int

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:

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:

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:

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:

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;
……

Tutte le lezioni

1 ... 44 45 46 ... 53

Se vuoi aggiornamenti su inizializzazione di una variabile puntatore inserisci la tua e-mail nel box qui sotto:
Tags:
 
X
Se vuoi aggiornamenti su inizializzazione di una variabile puntatore

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy