Newsgroup: it.comp.lang.c++
Titolo: dynamic_cast con puntatori void

Ho un problema con i cast con VC++ 2005. Sono in una condizione simile:
void FunctProblem(const void* p);
class A{};
class B:public A{};
void * pippo = new B[grosso numero];
FunctProblem(pippo);
dove
void FunctProblem(const void* p)
{
  // non compila
  const A* d1 = dynamic_cast<const A*>(p);
  // compila ma non mi piace
  const A* d2 = reinterpret_cast<const A*>(p);
  // compila, ma il controllo del tipo con RTTI viene fatto?
  const A* d3 = dynamic_cast<const A*>(reinterpret_cast<const A*>(p));
}

Davide Quack ha scritto:

A non deriva da void (ammesso che void possa essere paragonato ad una
classe), quindi come puo' funzionare il RTTI?
Devi salire di un livello, es.
class A{};
void FunctProblem(const A* p);
class B:public A{};
A * pippo = new B[grosso numero];
FunctProblem(pippo);
void FunctProblem(const A* p)
{
  const B* d1 = dynamic_cast<const B*>(p);
}

 }
Attenzione: A non è polimorfico (cioè non ha funzioni virtuali). Questo 
indica anche un grave errore presente nel codice.
Kiuhnm

Kiuhnm ha scritto:

Hai ragione, non mi ero soffermato sul codice e non avevo dato peso
alle {} dopo la dichiarazione di A.
Purtroppo, quando si posta codice minimale, spesso si sottindente cose
che non ci sono.

 }
Considera l'ipotesi di trasformare la tua funzione in un template.
Ciao,
Nicola

 Considera l'ipotesi di trasformare la tua funzione in un template.
Tecnicamente è già un template, ho postato un esempio semplificato.
Sto facendo un parser dei file che rilascia imdb ( 
http://www.imdb.com
 ). 
Questi file contengono informazioni su attori e filmografie annesse.
Il mio problema principale in questo momento è che devo maneggiare grosse
moli di dati, e di questo passo non mi basterà la ram. 
L'idea che avevo era che fare una malloc di 200 Mb di memoria in una botta,
e più veloce che fare un milione di new. Per questo poi mi è nata la
necessità di scorrere il mio blocco di memoria attraverso dei puntatori. 
Però ormai penso che si l'approccio iniziale errato. Se mi carico in
memoria attori e film (internamente lavoro un utf-16 per motivi che
non sto a spiegare) raggiungo facile il mezzo giga di spazio allocato. Se
provo a memorizzarle in utf-8 non cambia in realtà molto. Se uso una
libreria di storage via sql (posso usare qualsiasi DB con dei driver ODBC)
i tempi di elaborazione diventano assurdi.
Mi puoò anche stare bene avere dei transitori di 300 Mb di memoria occupata
quanto carico una serie di dati, ma poi mi servirebbe poterli mettere in
una sorta di vettore che sia parzialmente in memoria, e parzialmente su
file, e con tempi di risposta ad una ricerca che siano decenti (se devo
scorrere sempre il file dubito possa essere veloce, e una ricerca binaria
su file mi sembra tra l'altro scarsamente efficiente).
Qualcuno ha qualche idea per aiutarmi?

 Qualcuno ha qualche idea per aiutarmi?
La prima idea che mi viene in mente e': un database (con indici). Per 
esempio Berkley DB.
La seconda e': un file mappato in memoria.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 Qualcuno ha qualche idea per aiutarmi?
Implementa un sistema di caching per gestire gli scambi tra hard disk e 
memoria quindi virtualizza i puntatori ai campi usando iteratori che 
interagiscano con la cache e che leggano i dati da hard disk solamente 
quando necessario.
Questo è il modo più sicuro e corretto di procedere, secondo me.
Kiuhnm

 esempio Berkley DB.
Pardon, intendevo Berkeley DB (
www.sleepycat.com
).


 La seconda e': un file mappato in memoria.
Non ne vedo i vantaggi, ed è scarsamente portabile. Il F.S. poi al massimo
terrà una cache sequenziale, il che mi "impedisce" di usare la ricerca
binaria. Oserei dire che per la ricerca all'interno di un file mappato in
memoria, per quanto ordinato, ci vogliono degli algoritmi che non conosco.
Mi sembra strano però che non esista qualcosa di già fatto. L'ordinamento e
la ricerca di un file di grosse dimensioni dovrebbe essere un tema
ampiamente trattato. Non so bene però cosa cercare su google.
+++
Sull'allocazione di memoria ho visto su boost questo:
 
http://www.boost.org/libs/pool/doc/concepts.html
provo a darci un occhio.

 memoria, per quanto ordinato, ci vogliono degli algoritmi che non conosco.
Cerca che ti cerca ho trovato: 
http://stxxl.sourceforge.net
 che forse è
quello che mi serve. Tra l'altro ho visto che quelli che si occupano di
genetica hanno questo genere di problemi se non peggio.
Comunque (beata MIA ignoranza) ci ho messo un giorno per fare la query
magica su google per avere quel link.

 memoria, per quanto ordinato, ci vogliono degli algoritmi che non conosco.
Non so che cosa sia una "cache sequenziale", ma ti assicuro che in un 
file mappato in memoria puoi usare qualunque algoritmo di ricerca in 
memoria, compresa la "binary_search" di STL e la bsearch del C.
La limitazione consiste nel fatto che non puoi mappare in memoria piu' 
byte di quanti ne potresti allocare con una malloc.
Per quanto riguarda la portabilita', puoi usare una libreria che 
astragga dal sistema operativo, come la seguente:
http://www.boost.org/libs/iostreams/doc/classes/mapped_file.html


 memoria, compresa la "binary_search" di STL e la bsearch del C.
Sta probabilmente facendo riferimento al "look ahead" (forma di 
prefetching), ma temo si confonda con la cache della CPU. La RAM è 
suddivisa solitamente in pagine di grandi dimensioni (>= 4 KiB) quindi 
eseguire un cospicuo "look ahead" è controproducente. Sarà il 
programmatore a dover leggere le prime word di ogni pagina in modo da 
forzare il popolamento della cache.
Si vogliono usare le catene di Markov? Dipende dall'utente. Il sistema 
operativo si limiterà a una sorta di LRU. Probabilmente ogni SO presenta 
API per modifiacare le strategie usate.
Kiuhnm

 Si vogliono usare le catene di Markov? 
Sono ignorante in materia. Ho fatto qualche veloce ricerca con google e mi
sempre un approccio non alla mia portata. Il programma che sto facendo lo
faccio nel mio tempo libero, e non posso prendermi una seconda laurea per
arrivare in fondo. Poi l'approccio probabilistico nel mio caso non mi porta
nessun vantaggio.
Comunque mentre cercato mi sono imbattuto 
http://portal.acm.org/portal.cfm
Peccato non essere un ricercatore.

 memoria, compresa la "binary_search" di STL e la bsearch del C.
Si ma su un file mappato in memoria dipende fortemente da quanto č
intelligente il S.O. a fare la cache. In condizioni pessime comunque non
c'č santo, c'č un accesso al disco praticamente perenne.
Mi provo le stlxxl e poi vi so dire.

 Peccato non essere un ricercatore.
Prova 
http://citeseer.ist.psu.edu/
.
Ti conviene andare su google e scrivere
site:
citeseer.ist.psu.edu
 quello_che_vuoi_cercare
Kiuhnm

 superficie del disco.
Ho provato a fare un test stupido con la libreria stxxl.
Quasi una giornata per compilare la libreria e il resto della giornata per
fare un esempio cretino. Semplicemente impressionante. Usando la libreria
standard (vector e sort), l'ordinamento di un vettore di oggetti
parzialmente ordinato, per una dimensione complessiva di un 1 GB, aveva un
tempo di esecuzione biblico. Ovviamente io gli oggetti li allocavo
nell'heap in questo esempio. Usando il vettore della libreria, e usando il
suo algoritmo di ordinamento invece siamo sull'ordine dei secondi. Tra
l'altro usando questa libreria la memoria virtuale occupata era intorno ai
100 Mb. Il prezzo è ovviamente un uso di disco abnorme. Alla partenza, di
default, la libreria alloca un 1 GB di spazio su disco, giusto per gradire.
Ci vorranno dei mesi per capire come farla funzionare come voglio io, ma
questa libreria mi sembra quello che cercavo.

 default, la libreria alloca un 1 GB di spazio su disco, giusto per gradire.
Due strategie vengono probabilmente utilizzate:
1) soltanto le chiavi per la ricerca vengono mantenute nella memoria 
principale (questo diminuisce drasticamente l'accesso al disco);
2) la struttura dati usata è un albero multi-way ribilanciante (relaxed, 
probabilmente).
Kiuhnm

 probabilmente).
Questo non te lo so dire. Sono assolutamente ignorante in tema di
algoritmi. C'è un'abbondante bibliografia, ma quando leggo cose come:
"External Memory Spanning Forests and Connected Components" leggo arabo.
Vedo comunque dalle date che è tutta "roba" nuova.

 chiave (praticamente memorizzavo oggetti simili struct { char pluto[100]};
Pochissime volte è indispensabile usare l'intera chiave. E' sufficiente 
mantenere in memoria la parte iniziale.
Kiuhnm

 mantenere in memoria la parte iniziale.
Comunque esistono svariate tecniche. Non è molto diverso da quello che 
deve affrontare chi intende scrivere un filesystem (lo dovrò fare tra 
pochissimo).
Kiuhnm

 pochissimo).
Ti faccio i miei auguri. Scrivere un filesystem mi sembra un lavoro alla
portata di pochi. Immagina anche che da debaggare non sarą una passeggiata.

 portata di pochi. Immagina anche che da debaggare non sarà una passeggiata.
No, temo di no, ma il peggio sarà implementare i driver per controllare 
gli hard disk.
Kiuhnm

 pochissimo).
UAZZ!
Complimenti, sei un coraggioso :-)
O un disperato :-))
O un pazzo :-)))
Oppure ti pagano per farlo, nel qual caso gli epiteti di cui sopra si 
riferiscono ai tuoi superiori :-D
Non capisco però perchè ti crea tutto questo pensiero il fatto di 
scrivere i driver per gli HD: dopotutto c'è l'ATA (e/o lo SCSI) che li 
accomuna tutti e per il codice puoi prendere esempio (per esempio) dai 
driver di Linux... no?

 driver di Linux... no?
Perché mi hanno detto che è molto difficile creare driver veramente 
conformi alle varie versioni. Probabilmente dovrò esaminare il codice di 
Linux.
Kiuhnm

 In realtà sto realizzando un micro-OS.
Un micro-OS? O_o
Ti serve per un dispositivo embedded?

 Ti serve per un dispositivo embedded?
No, funzionerà su un normale PC, ma sarà comunque un SO specializzato. 
Per ora non posso veramente dire niente di più. Sorry...
Kiuhnm


sono due cose molto diverse e assolutamente distinte (e da tenere 
distinte!!).
Per Davide: scrivere un file system che possa essere genericamente 
migliore di quelli esistenti, certamente è dura.
Ma scrivere un filesystem in senso generale non è poi molto difficile.
Se non ti poni obiettivi assurdi si può fare abbastanza facilmente.
Sotto windows naturalmente fai prima a tirarti una rivoltellata.
Ma sotto linux ... puoi persino debuggarlo senza rischi: lo implementi 
in userspace e lo testi montando in loop un filettino al posto di un 
vero hard disk.

 distinte!!).
No, sono come le soluzioni complesse (in senso matematico).
Kiuhnm