PDA

View Full Version : [C] Errori di memoria(uso valgrind)


ndakota
15-09-2011, 10:20
Ciao a tutti, da ieri sto usando valgrind come supporto per lo sviluppo di questo progetto universitario che sto facendo. Ora, sono riuscito ad eliminare tutti i memory leaks, tant'è che l'output finale di valgrind è questo


==5421== HEAP SUMMARY:
==5421== in use at exit: 0 bytes in 0 blocks
==5421== total heap usage: 422 allocs, 422 frees, 2,625 bytes allocated
==5421==
==5421== All heap blocks were freed -- no leaks are possible


Però a parte questo, mi segnala un sacco di errori che non so risolvere. Il programma ora come ora se lanciato normalmente sbaglia un output proprio per gli errori di memoria anche se non dà errori. Mentre se lanciato con valgrind perfino l'output è giusto.
Qualcuno mi sa dire a cosa sono dovuti errori di questo tipo


==5421== Conditional jump or move depends on uninitialised value(s)
==5421== at 0x804A1C6: graph_print (graph.c:44)
==5421== by 0x8048758: main (main.c:43)
==5421==



==5421== Invalid read of size 4
==5421== at 0x8049F14: list_publication_author (util.c:446)
==5421== by 0x80487EA: main (main.c:55)
==5421== Address 0x41a24c8 is 0 bytes inside a block of size 8 free'd
==5421== at 0x4025BF0: free (vg_replace_malloc.c:366)
==5421== by 0x804936C: destroy_list (list.c:51)
==5421== by 0x8048796: main (main.c:47)
==5421==
==5421== Invalid read of size 1
==5421== at 0x407BD6E: vfprintf (vfprintf.c:1620)
==5421== by 0x408389F: printf (printf.c:35)
==5421== by 0x8049F26: list_publication_author (util.c:446)
==5421== by 0x80487EA: main (main.c:55)
==5421== Address 0x41a2500 is 0 bytes inside a block of size 4 free'd
==5421== at 0x4025BF0: free (vg_replace_malloc.c:366)
==5421== by 0x8049361: destroy_list (list.c:50)
==5421== by 0x8048796: main (main.c:47)
==5421==
==5421== Invalid read of size 1
==5421== at 0x40A3128: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1317)
==5421== by 0x407BC65: vfprintf (vfprintf.c:1620)
==5421== by 0x408389F: printf (printf.c:35)
==5421== by 0x8049F26: list_publication_author (util.c:446)
==5421== by 0x80487EA: main (main.c:55)
==5421== Address 0x41a2502 is 2 bytes inside a block of size 4 free'd
==5421== at 0x4025BF0: free (vg_replace_malloc.c:366)
==5421== by 0x8049361: destroy_list (list.c:50)
==5421== by 0x8048796: main (main.c:47)
==5421==
==5421== Invalid read of size 1
==5421== at 0x40A313F: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1317)
==5421== by 0x407BC65: vfprintf (vfprintf.c:1620)
==5421== by 0x408389F: printf (printf.c:35)
==5421== by 0x8049F26: list_publication_author (util.c:446)
==5421== by 0x80487EA: main (main.c:55)
==5421== Address 0x41a2501 is 1 bytes inside a block of size 4 free'd
==5421== at 0x4025BF0: free (vg_replace_malloc.c:366)
==5421== by 0x8049361: destroy_list (list.c:50)
==5421== by 0x8048796: main (main.c:47)
==5421==
==5421== Invalid read of size 1
==5421== at 0x40A30B0: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1349)
==5421== by 0x407BC65: vfprintf (vfprintf.c:1620)
==5421== by 0x408389F: printf (printf.c:35)
==5421== by 0x8049F26: list_publication_author (util.c:446)
==5421== by 0x80487EA: main (main.c:55)
==5421== Address 0x41a2500 is 0 bytes inside a block of size 4 free'd
==5421== at 0x4025BF0: free (vg_replace_malloc.c:366)
==5421== by 0x8049361: destroy_list (list.c:50)
==5421== by 0x8048796: main (main.c:47)
==5421==
==5421== Invalid read of size 1
==5421== at 0x40A30BC: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1348)
==5421== by 0x407BC65: vfprintf (vfprintf.c:1620)
==5421== by 0x408389F: printf (printf.c:35)
==5421== by 0x8049F26: list_publication_author (util.c:446)
==5421== by 0x80487EA: main (main.c:55)
==5421== Address 0x41a2502 is 2 bytes inside a block of size 4 free'd
==5421== at 0x4025BF0: free (vg_replace_malloc.c:366)
==5421== by 0x8049361: destroy_list (list.c:50)
==5421== by 0x8048796: main (main.c:47)
==5421==
==5421== Invalid read of size 4
==5421== at 0x8049F2A: list_publication_author (util.c:448)
==5421== by 0x80487EA: main (main.c:55)
==5421== Address 0x41a24cc is 4 bytes inside a block of size 8 free'd
==5421== at 0x4025BF0: free (vg_replace_malloc.c:366)
==5421== by 0x804936C: destroy_list (list.c:51)
==5421== by 0x8048796: main (main.c:47)
==5421==
==5421== Invalid read of size 4
==5421== at 0x8049F4F: list_publication_author (util.c:453)
==5421== by 0x80487EA: main (main.c:55)
==5421== Address 0x41a24cc is 4 bytes inside a block of size 8 free'd
==5421== at 0x4025BF0: free (vg_replace_malloc.c:366)
==5421== by 0x804936C: destroy_list (list.c:51)
==5421== by 0x8048796: main (main.c:47)
==5421==


Grazie a tutti :help:

marco.r
15-09-2011, 11:35
Conditional jump or move depends on uninitialised value(s)

sembra una variabile non inizializzata

ndakota
15-09-2011, 11:39
sembra una variabile non inizializzata

Ho "risolto" ma la cosa non mi convince. Nel main ho questo pezzo


case 'A':
p = get_publication();
headAuthors = p->authors;
headBibliography = p->bibliography;

if(check_publication_id(pubTree, p->id)
&& check_publication_authors(researchers, p->authors)
&& check_publication_bibliography(pubTree, p->bibliography))
{
add_publication_id(publicationIdGraph, p->id, p->bibliography);
graph_print(publicationIdGraph);
add_publication(&pubTree, &researchers, p);
}
/*
destroy_list(headAuthors);
destroy_list(headBibliography);*/
free(p->id);
free(p->title);
free(p);
break;


La situazione era questa. Prima di commentare le due righe commentate nel codice, valgrind mi segnalava una 70ina di errori però nessun memory leaks(tante malloc quante free). Commentate quelle due righe, gli errori da 70 sono scesi a 2 però mi perdo qualche free ovviamente. Ora non so che fare. Le ho lasciate commentate perchè così comunque funziona però non ho deallocato quelle due liste che fan parte della struttura.

marco.r
15-09-2011, 12:41
E' impossibile aiutarti se non pubblichi almeno il pezzo incriminato (la definizione di graph_print)
edit: Scusa avevo perso il pezzo dove dicevi che hai risolto.
Che errori ti segnalava ? Il problema in questi casi e' tipicamente NON dove fai la free, ma quanto il fatto che ci arrivi con dei puntatori sballati.
(i.e. il bug e' prima).

WarDuck
15-09-2011, 13:56
Probabilmente è la funzione destroy_list a non essere completamente corretta.

Dovresti postare il codice o comunque controllare lì dentro :D.

ndakota
15-09-2011, 14:03
La funzione è questa


void destroy_list(List l)
{
struct node * temp;

if(l == NULL)
return;

while(l != NULL)
{
temp = l->next;
free(l->value);
free(l);
l = temp;
}
}


Secondo me l'errore è nel case di prima. Io copio due puntatori ma se poi nella funzione modifico quello che ho assegnato a questi puntatori, quando viene chiamata la destroy_list non puntano più alla testa no? :mbe:
Ho bisogno di un po' di chiarezza :help:

marco.r
16-09-2011, 19:23
Vediamo troppo poco codice per poter capire, soprattutto perche' non si capisce bene a quali righe di codice si riferiscano gli errori dell'inizio.

Comunque, se il problema e' che facendo la free deallochi correttamente (ma poi accedi a memoria deallocata) e se non la fai poi ti resta memoria allocata alla fine dell'esecuzione, direi che il problema e' il seguente:

Probabilmente utilizzi anche da qualche altra parte i valori contenuti nella lista headAuthors o headBibliography, assegnando i puntatori invece che duplicandone il contenuto.

In alternativa potrebbe essere dovuto anche al fatto che quando distruggi la lista distruggi non solo la lista in se, ma anche i valori puntati.
Immagino ad esempio che diverse pubblicazioni possano avere uno stesso autore. In quel caso, condividono la stessa struttura, o si tratta di due copie distinte ?

ndakota
16-09-2011, 19:38
Vediamo troppo poco codice per poter capire, soprattutto perche' non si capisce bene a quali righe di codice si riferiscano gli errori dell'inizio.

Comunque, se il problema e' che facendo la free deallochi correttamente (ma poi accedi a memoria deallocata) e se non la fai poi ti resta memoria allocata alla fine dell'esecuzione, direi che il problema e' il seguente:

Probabilmente utilizzi anche da qualche altra parte i valori contenuti nella lista headAuthors o headBibliography, assegnando i puntatori invece che duplicandone il contenuto.

E' vero, solitamente assegno i puntatori. Come faccio a duplicarne il contenuto?



In alternativa potrebbe essere dovuto anche al fatto che quando distruggi la lista distruggi non solo la lista in se, ma anche i valori puntati.
Immagino ad esempio che diverse pubblicazioni possano avere uno stesso autore. In quel caso, condividono la stessa struttura, o si tratta di due copie distinte ?

No, no. Ogni pubblicazione ha la sua lista di autori. Che poi potrebbero essere gli stessi è un altro discorso. Comunque il progetto è diventato davvero grosso a livello di codice. Non ho nessun problema a mettere codice ma non so che parte mettere.

marco.r
16-09-2011, 23:09
E' vero, solitamente assegno i puntatori. Come faccio a duplicarne il contenuto?

Assegni il contenuto invece che il puntatore

Invece di

int* x;
int* y;
y = blabla();
x = y;


devi passare a qualcosa tipo


int* x;
int* y;
y = blabla();
x = malloc(sizeof(int));
*x = *y;

ndakota
17-09-2011, 09:44
Ok, il fatto è che ho strutture con campi struttura e stringa per esempio.
Come devo fare in questo caso? Basta che alloco la struttura e assegno solo la struttura o devo allocare ogni singolo campo e copiarli tutti? E poi se voglio deallocare l'intera struttura? Devo sempre prima deallocare un campo alla volta?