Newsgroup: it.comp.lang.c
Titolo: Problema di memoria (forse)

Salve!
Ho un problema con un programma scritto da me in C.
In breve il problema è questo: il mio programma (utilizzando una delle 
funzioni fornite dall'SDK di un sensore per il rilevamento i impronte 
digitali) deve confrontare tra di loro di svariate coppie di immagini e 
restituire il punteggio di somiglianza delle due impronte salvando i 
risultati su un file txt.
Il problema è che quando dico "svariate coppie di immagini", in realtà 
intendo dire che i confronti che il programma deve fare sono 1428000 (ebbene 
sì, quasi un milione e mezzo).
Ovviamente (almeno credo che sia ovvio), il mio programma dopo circa 500 
confronti esce e torna al prompt (senza nessun messaggio di errore) oppure 
addirittura fa flippare il computer.
Ho pensato di scomporre tutti i cicli for che generano le coppie da 
confrontare in modo da avere ogni volta un numero pari a 500 confronti ma 
dovrei effettuare questa modifca 2856 volte, e ogni volta rilanciare il 
programma modificando i parametri (in pratica dovrei fare a mano il ciclo 
for incrementando ogni volta a mano il contatore)... direi che la cosa non è 
fattibile.
Qualcuno sa suggerirmi un modo per affrontare la questione?
Grazie mille
-- 
Elminster 

 addirittura fa flippare il computer.
Non capisco il problema, se non c'e` abbastanza memoria:
- Carica immagine i
- Per k che va da i + k a MAX
  * Carica immagine i + k
  * Confronta
  * Libera immagine i + k
- Libera immagine i
- Incrementa i e ripeti
In ogni dato istante hai solo 2 immagini in memoria.
Inoltre "Ovviamente...esce e torna al prompt" non e` affatto ovvio. Se
un'allocazione fallisse da qualche parte senza che tu ne accorga avresti
molto presto un NULL pointer dereferenziato. Non e` che esce senza
errori perche` c'e` del codice come questo:
p = malloc(...)
if (!p)
        exit(EXIT_FAILURE);
Luca
-- 
Home: 
http://kronoz.cjb.net
"Vorrei morire ucciso dagli agi. Vorrei che di me si dicesse: ``Com'è
morto?'' ``Gli è scoppiato il portafogli''" -- Marcello Marchesi

 - Incrementa i e ripeti
In realtà io le immagini non le carico in memoria.
Ecco il codice che uso:
stream = fopen("ms.txt", "w");
differenza= fopen("diff.txt", "w");
    for (i=1; i<=6; i++) {
     for (k1=1; k1<=10; k1++){
      for (k2=k1; k2<=10; k2++) {
       if (k1!=k2) {
        s1 = creanome("C:", i, k1, j);
        s2 = creanome("C:", i, k2, j);
        f1 =  verifica(s1,s2);
        f2 =  verifica(s2,s1);
        fprintf(stream, "%f\n", f1);
        fprintf(stream, "%f\n", f2);
        fprintf(differenza, "%f\n", fabs(f1-f2));
        }
       }
      }
     }
    }
      fclose(stream);
        fclose(differenza);
}
Questo è il ciclo che effettua 10800 confronti, poi ne ho un altro che ne 
effettua un milione e mezzo.
La funzione creanome è una semplice funzione che a partire da 4 parametri 
(percorso e 3 contatori), restituisce una stringa così fatta 
<percorso>//i-k-j.tif
Verifica è la funzione dell'sdk che non fa altro che caricare le due 
immagini, effettuare il confronto e restituire un float che è uguale al 
"matching score" delle due impronte.
Bene, sia usando questo ciclo che usando quello più esteso, dopo circa 500 
ripetizioni il programma si impalla.
Son sicuro che non ci siano bug... il programma funziona egregiamente se
invece di lanciare un ciclo che va da 1 a 10mila lo lancio 20 volte ogni
volta impostando il ciclo da 1 a 500, da 501 a 1000, da 1001 a 1500, ecc.
Il problema avviene quando l'esecuzione diventa troppo "pesante"... capisci?
Per questo mi rivolgo a voi che di sicuro siete più esperti di me in
programmazione. Se create un programma che effettua un'operazione abbastanza
onerosa in termini di memoria (che so, potrebbe essere un task di
elaborazione di video o qualcosa di simile) e questa operazione la effettua
per un milione di volte di seguito, non è normale che a un certo punto il
programma esca perchè "non ce la fa più"? ;-)
Ripeto: parlo da inesperto, però mi sembrava abbastanza plausibile
ipotizzare che il programma si interrompesse per mancanza di memoria. Per
questo vi chiedevo se esisteva un modo per aggirare questo problema.
Attendo vostri pareri
Grazie mille (il programma mi serve per un progetto universitario quindi è
abbastanza importante)
-- 
Elminster 

 <percorso>//i-k-j.tif
In C una funzione non "restituisce un stringa", semmai restituisce un
puntatore a char. Come è allocato l'array di char il cui indirizzo è
restituito da 'creanome'?
Non mi sembra probabile sia una array statico (nel qual caso s1 e s2
avrabbero lo stesso valore), quindi sarà allocato con 'malloc'. Pertanto
dovrai chiamare 'free' da qualche parte, ma non mi sembra tu lo faccia.
Max

 restituito da 'creanome'?
La funzione creanome è la seguente:
char* creanome(char *path,int x,int y,int z)
{
 char *nomefiletif;
 nomefiletif=(char*)malloc(sizeof(char)*51);
 sprintf(nomefiletif,"%s\\%d-%d-%d.tif",path,x,y,z);
 return nomefiletif;
}
Poichè non sapevo dove collocare il free (mettendolo prima del return 
ovviamente poi non poteva restituire nulla), allora ho copiato questa 
funzione nella main che ora appare così (s1 e s2 sono due char*):
s1=(char*)malloc(sizeof(char)*51);
s2=(char*)malloc(sizeof(char)*51);
sprintf(s1,"%s\\%d-%d-%d.tif",path,i,k1,j);
sprintf(s2,"%s\\%d-%d-%d.tif",path,i,k2,j);
f1 =  verifica(s1,s2);
f2 =  verifica(s2,s1);
free(s1);
free(s2);
Beh, dopo circa 500 cicli il programma torna al prompt senza dire nulla (se 
lo lancio in Modalità Provvisoria di Windows) o da errore irreversibile (se 
lo lancio normalmente).
Ho anche provato a monitorare le risorse occupate tramite Task Manager ma ho 
visto che ovviamente l'uso della CPU durante l'esecuzione va al 99-100% ma 
comunque il programma non occupa mai più di 3500KB.
Non so più come fare... :-(
-- 
Elminster 

Posso suggerirti solo:
1 - Assicurati che le due malloc effettivamente restituiscano qualcosa:
s1 = (char *)malloc(51*sizeof(char));
s2 = (char *)malloc(51*sizeof(char));
if (s1)
{
   if (s2)
   {
     sprintf(...);
     sprintf(...);
     f1 = ...
     f2 = ...
     free(s2);
   };
   free(s1);
};
2 - Non allocare / deallocare sempre.
Forse ti conviene allocare una sola volta s1 ed s2, deallocarli alla 
fine e sovrascriverli (memset) durante l'esecuzione...
-- 
Quando noi ignoranti eravamo di piů, tutto era piů bello...
(A. Celentano)
Per rispondermi in privato, prima togli l'immondizia dalla testa.

 questo vi chiedevo se esisteva un modo per aggirare questo problema.
Che vada in crash per mancanza di memoria e` possibilissimo, anche se
non ci sono errori (in fondo la memoria e` _sempre_ limitata). In questi
casi tocca riprogettare gli algoritmi e le tecniche usate in modo da
usare di piu` lenti ma che risparmino memoria.
Nel tuo caso, come ho gia` detto, pare piu` un problema di memory leak.
Ti consiglio vivamente di
1) compilare attivando tutti i warning
2) compilare con le opzioni di debugging ed eseguire il codice tramite
    debugger
3) di scaricare Splint (
www.splint.org
), un analizzatore statico di codice
    C. Splint fa un'analisi molto piu` approfondita di quanto non faccia
    il compilatore: vedrai uscire fuori un'infinita` di warning abbastanza
    dettagliati, tra cui anche qualcuno sui memory leak
Saluti,
Marco
-- 
To email me, remove the no_ and _spam from my address.

 Ho un problema con un programma scritto da me in C.
Ragazzi, grazie a tutti... sono riuscito a risolvere il problema!!! :-)))
Praticamente l'errore era dovuto al fatto che ogni volta il ciclo rilanciava 
le due funzioni dell'SDK Init() e End().
Queste due funzioni evidentemente non fuzionavano correttamente e creavano 
dei memory leak (anche se in realtà il manuale stesso dell'SDK diceva che 
prima di ogni confronto doveva essere lanciata la Init e subito dopo la 
End).
In realtà però facendo così il programma dopo un po' si flippava: è bastato 
inserire la Init all'inizio della main e la End alla fine per risolvere 
tutti i problemi.
Grazie di cuore comunque a tutti per l'aiuto che mi avete dato (e per la 
vostra pazienza)! ;-)
-- 
Elminster