PDA

View Full Version : [C] problema allocazione, strutture, stringhe


ndakota
14-09-2011, 10:38
Ciao a tutti, non so spiegarvi bene il mio problema ma ho un pezzo di codice cortissimo che mi sta facendo impazzire. Eccolo


Bit_node bit_new(char* key)
{
Bit_node new = NULL;
printf("%s\n", key);
new = malloc(sizeof(struct bit_node));
printf("%s\n", key);


La funzione va avanti ma non importa. Il fatto è che alla prima stampa di key me la stampa giusta, la seconda, dopo che a new viene istanziato il puntatore a quella struttura allocata, key mi viene stampata con un carattere strano in coda! Non capisco proprio. Qualcuno riesce ad aiutarmi? :help:

Grazie.

clockover
14-09-2011, 11:08
Hai provato con un debugger a vedere cosa succede in memoria? Ma Bit_node cos'è un puntatore?

ndakota
14-09-2011, 11:16
Non ho mai usato un debugger. Appunto stavo usando le printf. Si Bit_node è un puntatore a struct bit_node.

clockover
14-09-2011, 11:22
Allora ti conviene cominciare ad usarlo, dato che solo con un debugger puoi davvero vedere cosa succede in memoria. Io sto imparando ad usare gdb, ma prima usavo il debugger di XCode.
Anche perchè in quel pezzo di codice che hai postato non c'è nulla di strano :confused:

ndakota
14-09-2011, 11:31
Appunto cavolo :muro:

clockover
14-09-2011, 11:32
Non c'è un altro thread che sta modificando il valore all'indirizzo di key vero?

ndakota
14-09-2011, 11:43
Non uso thread. Non che io sappia. Non faccio fork nè nient'altro insomma :cry:

banryu79
14-09-2011, 11:49
Ciao ndakota, se non lo conosci già, se e quando avrai tempo ti consiglio di cominciare a utilizzare questo -> Valgrind (http://valgrind.org/)

ndakota
14-09-2011, 11:54
Sto installando. Spero sia facile da usare perchè sto facendo sto progetto per l'università, non ho molto tempo ancora :doh:

banryu79
14-09-2011, 11:59
Sto installando. Spero sia facile da usare perchè sto facendo sto progetto per l'università, non ho molto tempo ancora :doh:
Io non l'ho mai usato, eh :stordita:
So solo (attraverso questo forum) che è uno strumento di diagnostica eccezionale.
Guardando l'home page, in alto a sinistra c'è un menù. La voce Tool Suite: sono i tool distribuiti con Valgrind. Leggiti qualcosa su questi e vedi di capire quale può fare al caso tuo (a naso, Memcheck?) e comincia ad utilizzarlo.

Poi al limite chiedi lumi, sicuramente tra gli utenti del forum c'è chi lo conosce bene e potrà darti le dritte giuste per il tuo debug.

ndakota
14-09-2011, 12:07
Ok, ho già visto come se ne fa un utilizzo di base. Però mi segnala cose che non mi sembrano errori e non saprei come correggere.. Tra l'altro se compilo ed eseguo con valgrind, mi stampa tutto correttamente. Dannato :mad:

banryu79
14-09-2011, 12:18
Però mi segnala cose che non mi sembrano errori e non saprei come correggere..
Se non sono errori probabilmente sono dei warning?


Tra l'altro se compilo ed eseguo con valgrind, mi stampa tutto correttamente. Dannato :mad:
Questo è interessante :D
Beh, come ho detto non ho conoscenze specifiche in merito, non ti resta che attendere più circostanziati consigli e nel frattempo provare a cavartela da te.
Ok, oggi mi sento un po' Captain Obvious™ :D

clockover
14-09-2011, 12:20
Io farei in questo modo
1) compila in questo modo
gcc -g sorgente.c
2) esegui il debugger
gdb -q ./a.out
3) lista il sorgente in gdb con questo comando e premi invio fino alle linee che ti interessando
list 1
4) leggi il numero di riga in cui si trovano le due printf e settali come breakpoint in questo modo (un comando per ogni riga)
Facendo così puoi vedere prima e dopo la malloc cosa succede
break #
# ovviamente è un numero
5) dai il comando
run
6)il programma viene eseguito e si blocca al primo breakpoint quindi dai il comando
x/s key
ti stampa il contenuto in formato stringa di key. Dando
x/#x key
ti stampa il contenuto in esadecimale e al posto di # inserisci un numero, ad esempio 1, 2, 3, 4, ecc..., dipende dalla dimensione di key
7)dai il comando
continue
8)ora si è fermato al secondo breakpoint e ripeti i comandi del punto 6. In questo modo puoi confrontare i valori in memoria e vedere se qualcosa è differente

spero di non aver sbagliato qualcosa dato che come ho già detto prima sto imparando ora ad usare gdb :-D

ndakota
14-09-2011, 12:31
Scusa clockover ma come ho detto non ho molto tempo. Cercherò di far qualcosa con le segnalazioni di valgrind altrimenti mi arrendo :(

ndakota
14-09-2011, 12:58
Ho risolto :D Grandissimi! E questo valgrind è veramente una figata ;)

banryu79
14-09-2011, 13:18
Ho risolto :D Grandissimi! E questo valgrind è veramente una figata ;)
Si può sapere qual'era il problema? Scusa se chiedo, ma la curiosità è bruciante :D

ndakota
14-09-2011, 14:22
Del caso specifico dell'open post non ne ho idea. Perchè la prima volta che l'ho lanciato mi ha dato tanti di quelli errori che ho pensato fosse meglio fare un passo indietro. Così mi sono messo a testare tutte le funzioni fatte da me ed erano piene di errori di memoria di vario tipo. Per esempio per molto non facevo una free, adesso per ogni allocazione ho una free. Altro errore per esempio, allocavo n byte ma in alcuni casi particolari ne scrivevo n-1 e lui lo segnalava. Adesso è tutto perfetto. Non mi segnala niente di niente :D

Unrue
14-09-2011, 16:08
Ho risolto :D Grandissimi! E questo valgrind è veramente una figata ;)

Altroché se è una figata :)

Ti consiglio di utilizzare SEMPRE questi flags quando lo lanci:

--tool=memcheck --leak-check=full

Ed ovviamente compilare con -O0 -g

Ciao.

banryu79
14-09-2011, 16:09
Valgrind colpisce ancora :)

ndakota
14-09-2011, 21:47
Cavolo ragazzi. Sono riuscito ad andare avanti ma più vado avanti più spuntano errori su valgrind. A volte non intaccano l'esecuzione, fila tutto perfettamente. Altre no e quindi poi mi trovo tra millemila errori. Qualcuno ha qualche suggerimento? Qualcuno che lo usa magari e sa dirmi gli errori più comuni e come si risolvono. Please :help:

clockover
14-09-2011, 21:57
Postali

ndakota
14-09-2011, 22:05
==4980== Memcheck, a memory error detector
==4980== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4980== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==4980== Command: ./main
==4980==
R
R
R
R
R
R
Autore No gia' presente
R
R
R
A
1 ->
==4980== Conditional jump or move depends on uninitialised value(s)
==4980== at 0x804A142: graph_print (graph.c:42)
==4980== by 0x8048727: main (main.c:40)
==4980==
A
Articolo 1 gia' presente
A
Autore Alloras inesistente
A
2 ->
1 ->
P
==4980== Invalid read of size 4
==4980== at 0x8049E88: list_publication_author (util.c:423)
==4980== by 0x80487BF: main (main.c:52)
==4980== Address 0x41a2508 is 0 bytes inside a block of size 8 free'd
==4980== at 0x4025BF0: free (vg_replace_malloc.c:366)
==4980== by 0x804933E: destroy_list (list.c:50)
==4980== by 0x8048768: main (main.c:44)
==4980==
==4980== Invalid read of size 1
==4980== at 0x407BD6E: vfprintf (vfprintf.c:1620)
==4980== by 0x408389F: printf (printf.c:35)
==4980== by 0x8049E9A: list_publication_author (util.c:423)
==4980== by 0x80487BF: main (main.c:52)
==4980== Address 0x41a2540 is 0 bytes inside a block of size 4 free'd
==4980== at 0x4025BF0: free (vg_replace_malloc.c:366)
==4980== by 0x8049333: destroy_list (list.c:49)
==4980== by 0x8048768: main (main.c:44)
==4980==
==4980== Invalid read of size 1
==4980== at 0x40A3128: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1317)
==4980== by 0x407BC65: vfprintf (vfprintf.c:1620)
==4980== by 0x408389F: printf (printf.c:35)
==4980== by 0x8049E9A: list_publication_author (util.c:423)
==4980== by 0x80487BF: main (main.c:52)
==4980== Address 0x41a2542 is 2 bytes inside a block of size 4 free'd
==4980== at 0x4025BF0: free (vg_replace_malloc.c:366)
==4980== by 0x8049333: destroy_list (list.c:49)
==4980== by 0x8048768: main (main.c:44)
==4980==
==4980== Invalid read of size 1
==4980== at 0x40A313F: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1317)
==4980== by 0x407BC65: vfprintf (vfprintf.c:1620)
==4980== by 0x408389F: printf (printf.c:35)
==4980== by 0x8049E9A: list_publication_author (util.c:423)
==4980== by 0x80487BF: main (main.c:52)
==4980== Address 0x41a2541 is 1 bytes inside a block of size 4 free'd
==4980== at 0x4025BF0: free (vg_replace_malloc.c:366)
==4980== by 0x8049333: destroy_list (list.c:49)
==4980== by 0x8048768: main (main.c:44)
==4980==
==4980== Invalid read of size 1
==4980== at 0x40A30B0: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1349)
==4980== by 0x407BC65: vfprintf (vfprintf.c:1620)
==4980== by 0x408389F: printf (printf.c:35)
==4980== by 0x8049E9A: list_publication_author (util.c:423)
==4980== by 0x80487BF: main (main.c:52)
==4980== Address 0x41a2540 is 0 bytes inside a block of size 4 free'd
==4980== at 0x4025BF0: free (vg_replace_malloc.c:366)
==4980== by 0x8049333: destroy_list (list.c:49)
==4980== by 0x8048768: main (main.c:44)
==4980==
==4980== Invalid read of size 1
==4980== at 0x40A30BC: _IO_file_xsputn@@GLIBC_2.1 (fileops.c:1348)
==4980== by 0x407BC65: vfprintf (vfprintf.c:1620)
==4980== by 0x408389F: printf (printf.c:35)
==4980== by 0x8049E9A: list_publication_author (util.c:423)
==4980== by 0x80487BF: main (main.c:52)
==4980== Address 0x41a2542 is 2 bytes inside a block of size 4 free'd
==4980== at 0x4025BF0: free (vg_replace_malloc.c:366)
==4980== by 0x8049333: destroy_list (list.c:49)
==4980== by 0x8048768: main (main.c:44)
==4980==
==4980== Invalid read of size 4
==4980== at 0x8049E9E: list_publication_author (util.c:425)
==4980== by 0x80487BF: main (main.c:52)
==4980== Address 0x41a250c is 4 bytes inside a block of size 8 free'd
==4980== at 0x4025BF0: free (vg_replace_malloc.c:366)
==4980== by 0x804933E: destroy_list (list.c:50)
==4980== by 0x8048768: main (main.c:44)
==4980==
==4980== Invalid read of size 4
==4980== at 0x8049EC3: list_publication_author (util.c:430)
==4980== by 0x80487BF: main (main.c:52)
==4980== Address 0x41a250c is 4 bytes inside a block of size 8 free'd
==4980== at 0x4025BF0: free (vg_replace_malloc.c:366)
==4980== by 0x804933E: destroy_list (list.c:50)
==4980== by 0x8048768: main (main.c:44)
==4980==
Boh & Icaro
P
Allora & No
Alan Turing
Allora
Boh
gino pino
Icaro
muimuimui
No
Zazza
1
2
==4980== Conditional jump or move depends on uninitialised value(s)
==4980== at 0x804A196: graph_destroy (graph.c:62)
==4980== by 0x8048837: main (main.c:74)
==4980==
==4980== Conditional jump or move depends on uninitialised value(s)
==4980== at 0x4025BB0: free (vg_replace_malloc.c:366)
==4980== by 0x8049FDD: destroy_list_g (list_graph.c:51)
==4980== by 0x804A1A2: graph_destroy (graph.c:68)
==4980== by 0x8048837: main (main.c:74)
==4980==
==4980== Conditional jump or move depends on uninitialised value(s)
==4980== at 0x8049FC6: destroy_list_g (list_graph.c:46)
==4980== by 0x8049FF3: destroy_list_g (list_graph.c:54)
==4980== by 0x804A1A2: graph_destroy (graph.c:68)
==4980== by 0x8048837: main (main.c:74)
==4980==
==4980==
==4980== HEAP SUMMARY:
==4980== in use at exit: 28 bytes in 4 blocks
==4980== total heap usage: 421 allocs, 417 frees, 2,627 bytes allocated
==4980==
==4980== 28 (12 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 3
==4980== at 0x4026864: malloc (vg_replace_malloc.c:236)
==4980== by 0x8049EF9: add_to_list_g (list_graph.c:8)
==4980== by 0x804A060: graph_vertexinsert (graph.c:21)
==4980== by 0x8049CF9: add_publication_id (util.c:362)
==4980== by 0x804871B: main (main.c:39)
==4980==
==4980== LEAK SUMMARY:
==4980== definitely lost: 12 bytes in 1 blocks
==4980== indirectly lost: 16 bytes in 3 blocks
==4980== possibly lost: 0 bytes in 0 blocks
==4980== still reachable: 0 bytes in 0 blocks
==4980== suppressed: 0 bytes in 0 blocks
==4980==
==4980== For counts of detected and suppressed errors, rerun with: -v
==4980== Use --track-origins=yes to see where uninitialised values come from
==4980== ERROR SUMMARY: 70 errors from 13 contexts (suppressed: 11 from 6)


Tra l'altro, il suo output è corretto xD

clockover
14-09-2011, 22:39
Con uno sguardo veloce sembra che tu stia leggendo dei blocchi di memoria liberati con free

ndakota
14-09-2011, 22:49
Di sicuro ho errori sulle strutture dati a questo punto o non si riprodurrebbero esponenzialmente :muro:

Floris
15-09-2011, 07:38
Se hai problemi con allocazione e successiva pulizia della memoria prova ad usare i puntatori smart. Dovrai però passare al C++.

ndakota
15-09-2011, 08:37
Niente C++, è da svolgere in ansi C.