PDA

Visualizza la versione completa : [C] Errore di allocazione memoria in lettura da file


drudox
29-09-2011, 07:06
Buon giorno a tutti .. è il mio primo tread ne approfitto per sottoporvi un problemino ..
stò implementando un semplice progammino per elaborare N file (una decina) passati come argomento dai quali leggere tre vettori dal primo per poi aggiungere in coda a questo i valori successivi letti dal secondo argomento ..
l'idea è quella di utilizzare un ciclo ... da 1 a argc e se l'indice è uno usare la malloc altrimenti utilizzare la realloc .. posto l'esempio e spiego il problema ..


#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int column( FILE *f );
int main( int argc , char *argv[]){
FILE *input ;
double *time , *temp ;
int i , k, *law , size = 0 , a , oldSize = 0 , j , ii = 0;

for( k = 1 ; k < argc ; k++){

if( (input = fopen( argv[k], "r" ) ) == NULL ){
printf("error open file input \n");
}
else
{
int n = column(input);
printf("n is %d\n" , n);

size += n;
if(k==1){
time = (double*)malloc(n*sizeof(double));
temp = (double*)malloc(n*sizeof(double));
law = (int*)malloc(n*sizeof(int));
}
else{
time = (double*)realloc( time , size * sizeof(double));
temp = (double*)realloc( temp , size * sizeof(double));
law = (int*)realloc( law , size * sizeof(int) );
}

rewind(input);

/*
do{
a = fgetc(input);
}while(a != '\n') ;
//i=0;

*/
while(!feof(input)){
fscanf( input, "%lg %lg %d", &time[ii] ,&temp[ii] , &law[ii] );
++ii ;
}

}

printf("oldSize is %d , size is %d\n" , oldSize , size);
oldSize = size ;
}

for( j=0 ; j < size ; j++ ){
printf("law[%d]: %d\n", j ,law[j]);

}
return 0 ;
}


int column( FILE *f){
int c ;
int n=0;

while(!feof(f)){
if( (c = fgetc(f) )== '\n'){
n++ ;
}
}
return n;
}

ora .. il problema è strano .. se io lascio "n" a moltiplicare l'argomento della malloc e passo più di quattro file come argomenti mi dà il seguente messaggio



oldSize is 0 , size is 746
n is 1142
oldSize is 746 , size is 1888
n is 1340
oldSize is 1888 , size is 3228
n is 746
*** glibc detected *** ./test: realloc(): invalid next size: 0x0000000001e54520 ***
======= Backtrace: =========
/lib/libc.so.6(+0x71ad6)[0x7f9e48d7aad6]
/lib/libc.so.6(+0x776ec)[0x7f9e48d806ec]
/lib/libc.so.6(realloc+0xf0)[0x7f9e48d80a00]
./test[0x40086e]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f9e48d27c4d]
./test[0x4006b9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:02 1711113 /home/marco/Scrivania/mild/test
00600000-00601000 rw-p 00000000 08:02 1711113 /home/marco/Scrivania/mild/test
01e49000-01e6a000 rw-p 00000000 00:00 0 [heap]
7f9e44000000-7f9e44021000 rw-p 00000000 00:00 0
7f9e44021000-7f9e48000000 ---p 00000000 00:00 0
7f9e48af3000-7f9e48b09000 r-xp 00000000 08:01 1438979 /lib/libgcc_s.so.1
7f9e48b09000-7f9e48d08000 ---p 00016000 08:01 1438979 /lib/libgcc_s.so.1
7f9e48d08000-7f9e48d09000 rw-p 00015000 08:01 1438979 /lib/libgcc_s.so.1
7f9e48d09000-7f9e48e61000 r-xp 00000000 08:01 1438987 /lib/libc-2.11.2.so
7f9e48e61000-7f9e49060000 ---p 00158000 08:01 1438987 /lib/libc-2.11.2.so
7f9e49060000-7f9e49064000 r--p 00157000 08:01 1438987 /lib/libc-2.11.2.so
7f9e49064000-7f9e49065000 rw-p 0015b000 08:01 1438987 /lib/libc-2.11.2.so
7f9e49065000-7f9e4906a000 rw-p 00000000 00:00 0
7f9e4906a000-7f9e49088000 r-xp 00000000 08:01 1438999 /lib/ld-2.11.2.so
7f9e49262000-7f9e49265000 rw-p 00000000 00:00 0
7f9e49280000-7f9e49287000 rw-p 00000000 00:00 0
7f9e49287000-7f9e49288000 r--p 0001d000 08:01 1438999 /lib/ld-2.11.2.so
7f9e49288000-7f9e49289000 rw-p 0001e000 08:01 1438999 /lib/ld-2.11.2.so
7f9e49289000-7f9e4928a000 rw-p 00000000 00:00 0
7fff8f2d8000-7fff8f2ed000 rw-p 00000000 00:00 0 [stack]
7fff8f3ff000-7fff8f400000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Abortito

se io invece che n metto un numero molto grande .. nessun problema ..
i file di argomento sono dei file di dati double contenenti non più di 200 colonne ciascuno ..

Spero possiate essermi d'aiuto..
Buona giornata

drudox
29-09-2011, 09:35
chiedo scusa .. 200 righe non colonne

oregon
29-09-2011, 09:59
E' un problema di corruzione della memoria ...

Fai un po' di debugging passo passo durante la lettura dei file.

drudox
29-09-2011, 10:03
Si che fosse un problema di corruzione ok .. ma non capisco il motivo .. neppure facendo il debug con DDD riesco a capirne il perche` ..
succede all'improvviso durante il terzo realloc ..
infatti se passo solo 3 file (di qualsiasi dimensione siano) non ricevo questa corruzione

oregon
29-09-2011, 10:19
Purtroppo un problema del genere lo risolvi con un buon debugging passo passo.

Il fatto che ti si presenti solo dopo il terzo file, può non essere indicativo (potrebbe essere un problema derivante dal quarto file, ma potresti provare ad indicarlo per primo, oppure potrebbe essere solamente il risultato dell' "accumulo" di scritture fuori dalla memoria allocate durante le prime letture ...).

Io mi concentrerei passo passo sulla lettura dei dati dal file (le fscanf) per capire se ne fa più di quelle previste ...

drudox
29-09-2011, 10:39
con 3 file anche cambiandone l'ordine (ad esempio mettendo il 4 per primo o altre 100 prove) il problema si riverifica.. :-(
Trovi che ci possa essere qualcosa che non vada ?
la scanf va bene ! difatto dal debug emerge che esce brutalmente durante i realloc .. non durante le fscanf

oregon
29-09-2011, 12:43
Esce durante la realloc perché la realloc trova la memoria corrotta.

La corruzione della memoria avviene in precedenza e tramite delle istruzioni che ci scrivono dentro. Ecco perché sospetto della fscanf (non della scanf ...).

Hai controllato con precisione che il ciclo legga da file per il numero di volte corretto o "sfora" la memoria allocata?

drudox
29-09-2011, 12:52
Purtroppo non sono espertissimo .. sopratutto nel debug :bhò: ma mi sembra di si ..
ti e` possibile fare una prova ? mi saresti davvero utile .. ci sto` provando e riprovando

oregon
29-09-2011, 12:56
Per fare una prova attendibile ci vogliono anche i file che utilizzi ...

drudox
29-09-2011, 14:46
niente di piu` semplice ..

crea un file "prova.dat" a caso ad esempio ho provato che si vericfica con questo



0.1 3.23 43
2 0.3 0.5 2

semplicemente passandolo quattro volte .. che so` :
./a.out prova.dat prova.dat prova.dat prova.dat

Loading