Newsgroup: it.comp.lang.c++
Titolo: come tenere aggiornato un registro (vettore) di puntatori..?

Ciao a tutti,
ho un problema in apparenza banale ma che forse e' un filo piu' complicato
del previsto e vorrei sapere se esiste qualche metodo standard per
risolverlo.
In pratica ho la seguente:
In run-time creo e distruggo tutta una serie di oggetti dello stesso tipo,
per tenere una traccia di tali oggetti (per deallocarli alla fine del
processo e per leggere le informazioni in essi contenute) definisco un
vettore di puntatori, un registro degli oggetti presenti in memoria.
Usando un vettore posso, da un lato incrementare "senza limiti" la lista e
dall'altro ho la sicurezza che sia sempre in forma "compatta" (posso
leggerelo sempre attraverso un normale ciclo sugli iteratori).
Il problema e' pero' come eliminare un puntatore dal vettore quando
l'oggetto viene deallocato!
Poiche nel frattempo avro' fatto latre operazioni di scrittura/rimozione,
non sapro piu' dove si trova il riferimento all'oggetto nel vettore.
Spero di essermi spiegato.
Faccio un esempio in metalinguaggio (SO che non compilerebbe..)
vector<oggetto*> lista_puntatori;
oggetto* crea_oggetto(){
        oggetto* oggetto_pt=new oggetto;
        lista_puntatori.push_back(oggetto_pt);
}
void distruggi_oggetto(oggetto* oggetto_da_eliminare){
        delete oggetto_da_eliminare;
        //-->e ora come elimino da lista_puntatori <--//
}
void leggi_lista_oggetti(){
        vector<oggetto*>::iterator iteratore;
        for(iteratore=lista_puntatori.begin() ; 
                iteratore!=lista_puntatori.end();iteratore++){
                        leggi_oggetto(lista_puntatori[iteratore]);
        }
}
Grazie          

 }
void distruggi_oggetto(oggetto*oggetto_da_eliminare) {
	for (vector<oggetto*>::iterator 
a=lista_puntatori.begin();a!=lista_puntatori.end();++a)
		if (*a==oggetto_da_eliminare){
		        delete oggetto_da_eliminare;
			lista_puntatori.erase(a);
			break;
		}
	}
}
Occhio che non e' il massimo dell'efficienza, se il vettore e' molto 
ampio...
  bye
	av.

Andrea Venturoli wrote:

Si lo so ed e' proprio questo il problema :(
Avevo gia' pensato a questa soluzione, ma ci sono troppi oggetti da
eliminare e alla lunga il vettore puo diventare grosso.
Comincio a pensare che non ci sia un metodo capace di salvaguardare sia le
prestazione che la memoria...
(infatti un alternativa poteva essere di non cancellare l'elemento ma
semplicemente di porlo a zero, in questo modo le informazione sul vettore
si frammentano (e il vettore si ingrossa...) ma non perdo le informazioni
sulla posizione nella lista.)

 Si lo so ed e' proprio questo il problema :(
potresti sempre provare ad utilizzare un albero per ridurre i tempi di 
ricerca


che ha delle classi per gestire gli smart pointer.
Comunque, piuttosto che usare un std::vector, ti consiglierei di usare 
un std::map, con il quale dovrebbe risultare molto efficiente "pescare" 
un oggetto all'interno della mappa.
Potresti usare delle coppie (nome_oggetto, puntatore); la chiave sarebbe 
"nome_oggetto".
Come "nome oggetto" potresti anche realizzare qualcosa tipo "Knnnn" con 
nnnn un numero incrementale globale, per i vari oggetti da inserire 
nello stesso container. La mappa[ nome_oggetto ] ti darebbe subito 
accesso al puntatore, che potresti deallocare e rimuovere dalla mappa.
Ciao
Dan

 prestazione che la memoria...
Utilizzo da tempo una libreria in C (Nlib per la cronaca) che implementa 
una cosa esattamente analoga a quella che fai tu.
La loro idea sarebbe:
a) che puoi evitare le deallocazioni, tanto poi fa tutto lui (una sorta 
di garbage collection dunque);
b) che comunque puoi fare il bravo bambino e deallocare di volta in 
volta, ma se ti scordi qualcosa...
Ora, secondo me:
La a) e' il modo migliore per esaurire comunque la memoria;
La b), una volta che passi al C++, diventa inutile; basta usare degli 
smart pointer.
Comunque, dopo aver fatto del profiling approfondito per ottimizzare il 
*mio* codice, e' risultato che le deallocazioni di tale libreria si 
pigliano una fetta non indifferente del tempo totale di esecuzione.
In definitiva, se effettivamente quello che cerchi e' "un metodo capace 
di salvaguardare sia le prestazione che la memoria", cambia strada 
subito (magari, come ti hanno suggerito altri, dai un'occhiata agli 
smart pointer di boost).
  bye
	av.