View Full Version : [C++] Quando è necessario usare esplicitamente delete e quando non ce n'è bisogno
E' un po' che devo coprire questa lacuna ma purtroppo il tempo scarseggia e non mi sono ancora documentato.
La mia domanda è semplice: quando devo usare delete esplicitamente?
Ad esempio se ho una classe con un puntatore ad un oggetto di un'altra classe, generalmente nel distruttore uso delete (con qualche eccezione).
Se ho una funzione con un puntatore di solito non lo faccio ma qui forse sbaglio.
Se ho una funzione con una variabile (non puntatore) non lo faccio mai.
Avrei bisogno di una documentazione completa a riguardo, avete qualche sito o anche libro in cui possa farmi un'idea completa su questo argomento?
lorenzo001
11-01-2014, 13:37
Veramente è semplice ... ad ogni new corrisponde una delete che farai quando quel dato/oggetto non ti serve più.
vendettaaaaa
11-01-2014, 13:40
Risposta "moderna": evita di usare puntatori nudi. Fine della storia.
Risposta più "tollerante":
- se nella funzione in cui ti trovi hai usato new per creare un oggetto, e alla fine della funzione l'oggetto non ti serve più, usa delete.
- se sei in una funzione che prende un puntatore come argomento, in genere non devi usare delete: il puntatore è un riferimento ad un oggetto creato fuori dalla funzione, quindi non spetta a te di doverlo distruggere, visto che dopo la chiamata a tal funzione l'oggetto probabilmente verrà ancora usato. Esempio:
Color* color = new Color("black");
changeColorToRed(color);
cout << "My color is now: " << *color << endl;
------
void changeColorToRed(Color* c)
{
c->name = "red";
return; // ovviamente non distruggo l'oggetto puntato da c...questa funzione serve solo a modificarlo
}
Più in generale, devi usare delete nelle parti di codice che hanno "ownership" degli oggetti creati con new, perchè non vengono automaticamente tolti dalla memoria, ma bisogna farlo a mano:
void compute()
{
int* matrix = new int[1000000000]; // alloco 1 miliardo di int
// faccio i conti e stampo a video i risultati
delete[] matrix;
}
int main()
{
for (int i = 0; i < 1000000; ++i)
compute(); // faccio per 1 milione di volte conti su una matrice
}
Se non liberassi la memoria con delete[] (delete cancella un oggetto; delete[] cancella un array) dopo qualche chiamata avrei la memoria satura e il programma crasherebbe.
Tornando alla risposta "moderna": storicamente chi scrive codice ha dimostrato che ricordarsi di liberare manualmente ogni risorsa allocata è praticamente impossibile in programmi di certe dimensioni (cioè in programmi di qualche utilità pratica), senza contare i casi in cui ci sono eccezioni e si salta la parte di codice che libererebbe le risorse, quindi usa unique_ptr<T> e shared_ptr<T>. Sono classi che si assicurano di liberare la memora automaticamente quando non serve più. unique_ptr si usa per oggetti la cui ownership è singola, mentre shared_ptr contiene oggetti a cui si possono riferire più entità.
Come avrai intuito è una discussione lunghissima, ma credo di aver riassunto abbastanza i concetti importanti. Per concludere, ora che abbiamo un C++ moderno e possiamo farlo, usa sempre unique_ptr e shared_ptr (così come vector anzichè gli array/i puntatori e string anzichè char*).
...
Grazie. Risposta dettagliatissima come sempre ;) . Mi documento sugli uniqque e shared ptr, a dire la verità non li ho mai usati.
E sto pure facendo applicazioni da mettere nel portfolio e mostrare alle aziende dunque direi che è ora di metterci le mani.
Grazie!
vendettaaaaa
11-01-2014, 18:30
Prego. Leggiti anche qualcosa sul concetto più ampio di RAII (resource acquisition is initialization) e come questa tecnica aiuti a rendere superfluo il garbage collector ed estende la soluzione al problema dei puntatori (cioè la eliminazione automatica della memoria allocata) alle risorse di qualsiasi tipo (ad esempio, la chiusura di un file per renderlo disponibile ad altri utilizzatori non devi gestirla manualmente, districandoti tra eccezioni e salti condizionati, ma è garantita dall'oggetto che lo apre).
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.