Ordinamento File [c]

Gasso1
Salve a tutti, ho un problema con il seguente codice:
void Ordinamento(FILE *in,FILE *out){
char tnome[dim]="",tcogn[dim]="",tnum[dim]="";
int i=0,j=0,y=0,last;
persona *temp;
temp=(persona*)malloc(sizeof(persona));

while(!feof(in)){//leggo da file e scrivo in temp[i]
	fscanf(in, "%s %s %s\n", temp[i].cognome,temp[i].nome,temp[i].numero);
	i++;
}
last=i-1; 
for (i = last; i>0; i--)
	for(j = 1;j<=i;j++)
             if (strcmp (temp[j].cognome,temp[j-1].cognome) <0){
                strcpy (tnome, temp[j].nome);
                strcpy (temp[j].nome, temp[j-1].nome);
                strcpy (temp[j-1].nome, tnome);
		strcpy (tcogn, temp[j].cognome);
                strcpy (temp[j].cognome, temp[j-1].cognome);
                strcpy (temp[j-1].cognome, tcogn);
		strcpy (tnum, temp[j].numero);
                strcpy (temp[j].numero, temp[j-1].numero);
                strcpy (temp[j-1].numero, tnum);
             }

for (y = 0; y<=last; y++)
	fprintf(out, "%s %s %s\n", temp[y].cognome, temp[y].nome, temp[y].numero);

}

che effettua l'ordinamento di un file in ingresso e restituisce il file ordinato per cognome.Ho utilizzato la seguente struttura:
#define dim 20
typedef struct persona {
	char cognome[dim];
	char nome[dim];
        char numero[dim];
}persona;


Effettivamente l'ordinamento avviene. Infatti nel file "out" ci sono i dati del file "in" però ordinati.
Il problema è che dopo aver ordinato mi compare il "Segmentation fault" e non mi fa andare avanti.
Vorrei capire come risolvere questo problema, è da 2 giorni che ci sto dietro ma non riesco a trovare una soluzione.
Grazie in anticipo per l'aiuto.

Risposte
vict85
Hai allocato solo un elemento di tipo persona, dopo di che il puntatore ha proseguito nella memoria senza controllo fino alla fine della memoria allocabile (richiamando poi il Segmentation fault). Devi "contare le persone", poi allocare. Oppure usare metodi di allocazioni dinamica più complessi.

Gasso1
Grazie per la risposta.
Ho modificato il codice, praticamente ora quando inserisco una nuova persona su file, incremento una variabile e la passo all' Ordinamento:
void Ordinamento(FILE *in,FILE *out,int conta)

dopodichè alloco:
persona *temp;
temp=(persona*)malloc(conta*sizeof(persona));


Non mi da più Segmentation Fault ma una cosa del genere:
*** glibc detected *** ./server1: double free or corruption (!prev): 0x091b3008 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x6ff22)[0x6aff22]
/lib/i386-linux-gnu/libc.so.6(+0x70bc2)[0x6b0bc2]
/lib/i386-linux-gnu/libc.so.6(cfree+0x6d)[0x6b3cad]
/lib/i386-linux-gnu/libc.so.6(fclose+0x154)[0x69f414]
./server1[0x8049340]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x659113]
./server1[0x80489a1]
======= Memory map: ========
001a1000-001bd000 r-xp 00000000 08:01 918459     /lib/i386-linux-gnu/libgcc_s.so.1
001bd000-001be000 r--p 0001b000 08:01 918459     /lib/i386-linux-gnu/libgcc_s.so.1
001be000-001bf000 rw-p 0001c000 08:01 918459     /lib/i386-linux-gnu/libgcc_s.so.1
002fe000-0031c000 r-xp 00000000 08:01 918529     /lib/i386-linux-gnu/ld-2.13.so
0031c000-0031d000 r--p 0001d000 08:01 918529     /lib/i386-linux-gnu/ld-2.13.so
0031d000-0031e000 rw-p 0001e000 08:01 918529     /lib/i386-linux-gnu/ld-2.13.so
00640000-007b8000 r-xp 00000000 08:01 918534     /lib/i386-linux-gnu/libc-2.13.so
007b8000-007ba000 r--p 00178000 08:01 918534     /lib/i386-linux-gnu/libc-2.13.so
007ba000-007bb000 rw-p 0017a000 08:01 918534     /lib/i386-linux-gnu/libc-2.13.so
007bb000-007be000 rw-p 00000000 00:00 0 
00fe0000-00fe1000 r-xp 00000000 00:00 0          [vdso]

Da che cosa può dipendere?

vict85
Prova ad usare calloc. E ricordati di liberare la memoria.

http://www.cplusplus.com/reference/clib ... ib/calloc/ (è un reference del c++ ma la funzione è la stessa)

Gasso1
Provato con la calloc:
temp=(persona*)calloc(conta,sizeof(persona));

e a liberare la memoria allocata con free(temp) dopo l'ordinamento ma niente, mi compare sempre lo stesso errore.

vict85
Quante volte hai liberato la memoria? Perché il problema sembra dire che l'hai fatto più di una volta.

Gasso1
Quando mi è comparso la prima volta l'errore non l'avevo mai liberata, ora ho messo un free(temp) dopo l'ordinamento e mi da sempre lo stesso errore.

vict85
Senza avere il codice davanti è difficile capire cosa succede.

Gasso1
Sono un cretino io, riguardando il codice main c'era un fclose() di troppo. Ora gira bene, grazie cmq per l'aiuto!

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.