Salve gente.
Il container Vector appartenente alla Standard Template Library (STL) del C++ presenta un aspetto poco noto/chiaro che talvolta può provocare errori infidi, per esempio dei memory leak.
Se si crea un Vector di oggetti totalmente statici (intendo che non sono puntatori nè contengono puntatori) e poi lo si svuota con clear() o se ne eliminano elementi con erase() non ci sono problemi.
Prima di cancellare un elemento, verrà infatti invocato il suo distruttore per cui non viene persa memoria.
Ma se il vettore ha come elementi dei puntatori?
Bisogna fare attenzione perchè in questo caso toccherà al programmatore eliminare esplicitamente gli oggetti puntati!
Consideriamo il seguente codice (testato su MacOSX Leopard 10.5.3 con G++ 4.0.1, ma dovrebbe funzionare tranquillamente anche su altri SO Unix-like come Linux):
/*
FILE: vector_clean.cpp
AUTORE: Gian Paolo "JP" Ghilardi
LICENZA: GPL v2.0 (only)
COMPILARE COME: g++ -Wall -parentheses -pedantic vector_clean.cpp -o vector_clean
ESEGUIRE COME: ./vector_clean
*/
#include <vector>
#define VECTOR_SIZE 10
using namespace std;
int main(int argc, char**argv)
{
vector<int*> intVector; // vettore di puntatori a intero (statico)
int* myInt; // puntatore a intero
for(unsigned int i=0; i<VECTOR_SIZE; i++)
{
myInt=new int; // creiamo un intero-oggetto
intVector.push_back(myInt); // lo accodiamo nel vettore
}
for(unsigned int i=0; i<intVector.size(); i++)
{
// ATTENZIONE: questo loop è importantissimo!
delete intVector[i]; // eliminiamo uno a uno gli interi-oggetto
}
intVector.clear(); // possiamo cancellare i riferimenti agli elementi
}
Senza il loop che cancella esplicitamente tramite delete gli oggetti-elementi del vettore (che sono puntatori) si avrebbe un memory leak!
Per maggiori informazioni vedere questo post (ce ne sono molti altri, ovviamente, ma questo mi è piaciuto
).
Ciau.
Ciao,
mi ero perso questo post :p altrimenti l’avrei già commentato
Hai perfettamente ragione, e proprio per questo è sempre conveniente affidarsi agli smart_pointer (i.e., semplificando al massimo, oggetti statici che “simulano” il comportamento dei puntatori e che fanno da facade ad un vero puntatore memorizzato privatamente).
Prevengo una tua obiezione: lo so che lo standard (per ora) ci da solo auto_ptr (che implementa la politica di possesso) e che è un poco limitato per utilizzi complessi, ma esistono librerie di terze parti (qualcuno ha detto boost? :p) che forniscono ottime soluzioni… e poi, se non ricordo male, nella prossima versione dello standard dovrebbero esserci più smart_pointer a disposizione
cheers
Basta aspettare la prossima revisione dello standard che include buona parte delle Boost (noto anche come “piccole Boost crescono”
)…