PDA

View Full Version : [C] Chiamare delete su un iterator


-Ivan-
18-11-2013, 11:09
Sono sempre dietro a fare esercizi in C++, non credo di aver capito bene cosa faccia questo codice (l'ultimo for):


vector<MyClass*> elements;

for( int i=0; i < 512; ++i )
elements.push_back(new MyClass);

for( vector<MyClass*>::iterator j = elements.begin(); j != elements.end(); ++j )
delete *j;


Debuggando mi sono accorto che l'ultimo for non fa altro che richiamare il distruttore per gli oggetti ma non li elimina.

Quel che so è che gli iterator sono puntatori, dunque j è un puntatore a oggett MyClass*.
Quando eseguo delete *j quindi sto dicendo di liberare lo spazio in memoria dell'oggetto MyClass* che, per quel che ne so, dovrebbero essere gli elementi dentro al vettore.

So che l'intero ciclo for può essere eliminato e può essere richiamato semplicemente empty() sul vettore se l'obietto è solo svuotarlo ma in questo caso i distruttori non vengono richiamati ed io ho bisogno di farlo.

Cercando su internet ho trovato che la soluzione potrebbe essere:

delete * j;
j = elements.erase(j);

però non ho trovato la spiegazione del perchè.

-Ivan-
18-11-2013, 12:59
questo non e' C... :mbe:

Hai ragione anche te...modificato.

vendettaaaaa
18-11-2013, 14:07
Sono sempre dietro a fare esercizi in C++, non credo di aver capito bene cosa faccia questo codice (l'ultimo for):


vector<MyClass*> elements;

for( int i=0; i < 512; ++i )
elements.push_back(new MyClass);

for( vector<MyClass*>::iterator j = elements.begin(); j != elements.end(); ++j )
delete *j;


Debuggando mi sono accorto che l'ultimo for non fa altro che richiamare il distruttore per gli oggetti ma non li elimina.

Quel che so è che gli iterator sono puntatori, dunque j è un puntatore a oggett MyClass*.
Quando eseguo delete *j quindi sto dicendo di liberare lo spazio in memoria dell'oggetto MyClass* che, per quel che ne so, dovrebbero essere gli elementi dentro al vettore.

So che l'intero ciclo for può essere eliminato e può essere richiamato semplicemente empty() sul vettore se l'obietto è solo svuotarlo ma in questo caso i distruttori non vengono richiamati ed io ho bisogno di farlo.

Cercando su internet ho trovato che la soluzione potrebbe essere:

delete * j;
j = elements.erase(j);

però non ho trovato la spiegazione del perchè.
La soluzione è corretta, ma io farei
for ([...])
delete *j;
elements.empty(); // (se empty fa quel che dici, non ricordo ma mi fido).

Il perchè è: con lo statement delete cosa fai? Ottieni l'oggetto corrispondente all'iteratore, con l'operatore di dereferenziazione, che è un puntatore ad oggetto, poi chiami il delete su quel puntatore, quindi liberi la heap (la memoria dinamica) dall'oggetto puntato dal puntatore. Cioè
delete *j;
è equivalente a:
MyClass* tempPointer = *j;
delete tempPointer;
A questo punto il tuo puntatore punta a una zona di memoria dove non c'è più un oggetto, però il puntatore in sè, che è una variabile, rimane nel vettore.
A questo punto con elements.empty cancelli dalla memoria tutti gli elementi del vettore, cioè i puntatori a oggetti MyClass che non puntano più a niente.

Claro?

-Ivan-
18-11-2013, 16:26
...


Clarissimo, grazie!