Newsgroup: it.comp.lang.c++
Titolo: Lista di puntatori

se ho una lista (list della STL) di puntatori a oggetti, e questi non hanno
il distruttore (basta quello di default), vengono poi cancellati
"effettivamente" gli oggetti nella lista? altrimenti, come posso fare?


Sperando di non aver fatto errori:
list<oggetti*>::iterator b = lista.begin();
for (; b < lista.end(); b++) {
	// Fai cio che vuoi con *b
	delete b; // Chiamo il distruttore e libero la memoria allocata
}
remove(lista.begin(), lista.end());
dovrebbe funzionare.
-- 
Andrea Bergia - studente
Linux Registred User #281550

 
Scorri la lista e invochi delete sui vari elementi (assumo chiaramente che
i vari oggetti siano stati allocati con new).
Ovviamente, se (deliberatamente o per errore) viene inserito nella lista
lo stesso indirizzo più di una volta, sei nei pasticci.
Max

 dovrebbe funzionare.
Non mi risulta che codesto metodo funzioni, dato che un oggetto deletato
dalla memoria senza essere erasato dalla lista,
crea diversi problemi al list.(In particolare all'operatore ++)
Io normalmente uso questo ciclo di cancellazione:
list<oggetto*>::iterator It;
oggett* temp;
while(!Lista.empty()){
    It=Lista.begin();
    temp=(*It);
    Lista.erase(*It);
    delete temp;
}
Con questo sei sicuro che sono tutti dealloccati, e che la lista e 'vuota.
Joshi

 ha scritto nel messaggio
news:3D63D38C...@yahoo.it...


 remove(lista.begin(), lista.end());
Come ha gia scritto Joshi-Lg anch'io preferisco fare così:
typedef  list<oggetti *>::iterator  ITEROGGETTI;
while(!Lista.empty()){
    ITEROGGETTI iterOggetti = lista.begin();
    delete (*iterOggetti);
    lista.erase(iterOggetti);
}
ma non uso un puntatore temporaneo, del quale non ne vedo la necessità


 }
Questo sistema č dispendioso. Nel caso di list<> dove erase č O(1) non ci
sono problemi, ma se tu usassi un vector<> le cose cambierebbero.
Meglio chiamare delete su ciascuno elemento (e assegnargli il valore
nullo, se siamo preoccupati per la ragione sopra), quindi invocare clear()
alla fine.
Max

 lo stesso indirizzo pių di una volta, sei nei pasticci.
e questo errore usando gli auto_ptr non puo succedere ovviamente

 e questo errore usando gli auto_ptr non puo succedere ovviamente
Cattivissimo consiglio. gli auto_ptr non devono essere usati come
elementi dei container. Una buona implementazione della libreria non
dovrebbe consentirlo, ed anche se e' possibile dichiarare una cosa del
genere e' molto probabile che gli oggetti che inserisci vengano
distrutti durante la manipolazione del container stesso.
Piuttosto si puo' usare uno smart pointer con reference count, come
boost::shared_ptr - vedi 
www.boost.org
.
Ciao,
Nicola

 distrutti durante la manipolazione del container stesso.
In effetti lo Standard proibisce containers di auto_ptr.  Puo' provare
qualcosa come quello che segue (non testato :-)
// Definisce un oggetto funzionale che invoca operator delete su
// un pointer alla classe Obj, e poi assegna NULL al pointer
struct deletePointed : public std::unary_function<Obj * &, void> {
  void operator () (Obj * & p) { delete p; p=0; }
};
// Definisce ed usa un container di pointers a Obj.  Proma che esca
// di scopo, alla fine chiama:
std::for_each(container.begin(), container.end(), deletePointed());
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy          loreti at pd dot infn dot it

 essere problematico, ma per una ragione piuttosto sottile.
Credo che vi state confondendo per un errore iniziale di Ivank:
Lui ha scritto
list<oggetti*>::iterator b = lista.begin();
for (; b < lista.end(); b++) {
        // Fai cio che vuoi con *b
        delete b; // Chiamo il distruttore e libero la memoria allocata
}
remove(lista.begin(), lista.end());
In realtà doveva scrivere
list<oggetti*>::iterator b = lista.begin();
for (; b < lista.end(); b++) {
        // Fai cio che vuoi con *b
          // notare l'asterisco
        delete *b; // Chiamo il distruttore e libero la memoria allocata
 
}
remove(lista.begin(), lista.end());

 Credo che vi state confondendo per un errore iniziale di Ivank:
No. Il mio discorso non c'entrava niente con quello. Non credo nemmeno che
stessi parlando della stessa cosa che aveva in mente Joshi-Lg.  Stavo
soltanto sottolineando che la scelta, apparentemente "innocua", di
lasciare (temporaneamente) in un container dei puntatori con valori non
validi (perchč giŕ "deletati") potrebbe (in linea teorica) produrre
"undefined behaviour", anche se non abbiamo intenzione di dereferenziare
tali puntatori. Infatti, parrebbe che, secondo lo Standard, anche la
semplice operazione di copia (di un puntatore non valido) non sia
"legale", e i container hanno il diritto di effettuare copie dei propri
elementi. (Che poi non esista nessuna implementazione ragioneve in cui la
copia di un puntatore non valido produca problemi, č un altro discorso.)
Max

 copia di un puntatore non valido produca problemi, è un altro discorso.)
io non ho lo standard, ma se quello che dici e' vero, allora anche il 
seguente codice non e' valido:
int main() {
	void *p;
	void *a=p;
	//e soprattutto non avrebbe senso
	void *c=0;
	void *k=c;
}
Mi sembra strano! e poi non riesco a capire come copiare un puntatore 
non valido possa infastidire un sistema... perche' questa limitazione? 
ci sono dei casi che mi sfuggono?
saluti

 non valido possa infastidire un sistema... 
Uno dei partecipanti al thread che ho indicato sopra, tra le altre cose,
dice:
 
   From: Niklas Matthies (news/
comp.s...@nmhq.net
)
   There were hardware architectures in the past (and probably still
   existing) that check the validness of an address when loading it into
   an address register, and raise some hardware exception if it is
   invalid.
 
http://google.com/groups?selm=9csn10%24fafds%242%40ID-3706.news.dfncis.de
Max

         delete *b; // Chiamo il distruttore e libero la memoria allocata
Centrato in pieno, solo che nel testo, come giustamente nota Max, io ho
parlato di deletazione dell'oggetto puntato. Mi ero ingolfato nella
digitazione :-p
Joshi