Precedente :: Successivo |
Autore |
Messaggio |
saetta Eroe in grazia degli dei

Registrato: 25/02/08 11:52 Messaggi: 129
|
Inviato: 31 Mar 2008 12:03 Oggetto: gestione errori in c |
|
|
Salve, sto scrivendo (o meglio debuggando ormai...) una libreria per la gestione di grafi in c.
ho scritto le varie funzioni includendo dei controlli sui parametri in ingresso e con dei controlli sulle malloc del tipo:
1)
Codice: | ...
if(grafo == NULL)
{
errno = EINVAL;
perror("Funzione aggiungi_nodo");
return -1;
}
else...
|
2)...
Codice: | if(!(n=(nodo_t *)malloc (sizeof(nodo_t))) )
{
errno = ENOMEM;
perror("Funzione aggiungi_nodo");
return -1;
}
else ...
|
ho un test per vedere se le varie situazioni sono gestite bene dove appunto ho usato perror() per i controlli:
Codice: | if(aggiungi_nodo(grafo, etichetta_nodo)==-1)
{
perror("errore aggiungendo nodo");
exit(EXIT_FAILURE);
} |
ORA LA DOMANDA!!!
nella libreria(non nel test!!!) devo usare la perror() oppure no? Ho visto che se le lascio, in alcuni punti il debugger gdb mi segnala l'uscita dal programma con -1 (dunque non è andato tutto bene) mentre se le commento il programma di test termina normalmente.
Non sono riuscita a trovare spiegazioni esaurienti su come si gestiscono gli errori in c, insomma non ho ben chiaro cosa è necessario e cosa no.
Grazie per l'attenzione.
Saetta |
|
Top |
|
 |
saetta Eroe in grazia degli dei

Registrato: 25/02/08 11:52 Messaggi: 129
|
Inviato: 01 Apr 2008 11:31 Oggetto: Memory leak |
|
|
ancora non mi sono levata il dubbio sulle perror... e credo che anche i problemi che ho ora sono in qualche modo connessi ai casini che ho fatto con le perror.
1) se malloc va male setta automaticamente errno?
2)se malloc va male devo fare una free sul puntatore che davo alla malloc?
Codice: | if( (p=(...)malloc(sizeof ...))== NULL )
{
...
free(p); /*????????????????*/
...
} |
sto facendo il testing esportando la mtrace.log e mi da errore "memory not freed " e mi indica le righe dove ci sono le malloc... è il famoso memory leak?
Cosa mi devo assicurare di aver fatto con quelle "maledette" malloc?
AIUUUUUUUUTO! |
|
Top |
|
 |
SverX Supervisor Macchinisti


Registrato: 25/03/02 12:16 Messaggi: 11809 Residenza: Tokelau
|
Inviato: 01 Apr 2008 11:42 Oggetto: Re: Memory leak |
|
|
su questo ti posso aiutare:
saetta ha scritto: | se malloc va male devo fare una free sul puntatore che davo alla malloc? |
no, se malloc non alloca memoria allora non c'è memoria da liberare.
(e riguardo ai memori leak... il problema è quando allochi della memoria da qualche parte e poi ti 'perdi' il puntatore... quella memoria è 'abbandonata' a se stessa e non sarai più in grado di deallocarla...) |
|
Top |
|
 |
saetta Eroe in grazia degli dei

Registrato: 25/02/08 11:52 Messaggi: 129
|
Inviato: 01 Apr 2008 12:04 Oggetto: |
|
|
Grazie
Non so cosa posso aver combinato... Ma tanto ha sempre ragione lui!!!
mmm ...
per esempio alloco un ptr per una struttura e alla fine della funzione lo ritorno... se è andato tutto bene.
E Lui mi segna la riga con "memory not freed"
Codice: | if( (g=(grafo_t*)malloc(sizeof(grafo_t )))==NULL ) /*<------QUI*/
{
errno = ENOMEM;/*che credo non ci voglia, lo fa la malloc...forse*/
return NULL;
} |
AAARRRGGHHH |
|
Top |
|
 |
SverX Supervisor Macchinisti


Registrato: 25/03/02 12:16 Messaggi: 11809 Residenza: Tokelau
|
Inviato: 01 Apr 2008 13:07 Oggetto: |
|
|
dal segmento di codice capisco poco di quello che stai facendo... e quando le cose non funzionano bene io di solito cerco di semplificare il più possibile: ad esempio potresti non fare l'assegnazione a g della malloc e il confronto con NULL all'interno dell'IF ma separare in due parti distinte... non si sa mai con le precedenze, sai  |
|
Top |
|
 |
saetta Eroe in grazia degli dei

Registrato: 25/02/08 11:52 Messaggi: 129
|
Inviato: 02 Apr 2008 11:32 Oggetto: mmm |
|
|
Credo di aver fatto dei casini con le funzioni che rimuovono risp. nodi, archi e l'intero grafo.
Almeno, è l'unica cosa a cui mi posso appellare anche se rileggendo le funzioni sembrano a posto.
Sicuramente non libero tutta la memoria come dovrei. Non vedo dove però. |
|
Top |
|
 |
saetta Eroe in grazia degli dei

Registrato: 25/02/08 11:52 Messaggi: 129
|
Inviato: 02 Apr 2008 20:08 Oggetto: |
|
|
Analizzando il log della funzione mtrace() e facendo un test con make, vedo che mi segna tutte le righe dove compare malloc() con "memory not freed"
Dunque l'errore sta nelle funzioni di rimozione di archi, nodi e grafo.
Ad esempio ho postato un pezzo della f.ne che rimuove archi... non riesco a vedere cosa non dealloco o se non considero un qualche caso. Nonostante che non sia proprio ottimizzata, vi chiedo un indizio.
Vedete cosa sto tralasciando?
(Il grafo è implementato con liste di adiacenza )
nodes è ptr a nodo(lista di nodi, campo della struttura grafo)
adj è un ptr ad arco (campo della struttura grafo)
label è un campo sia della struttura nodo che della struttura arco
nodi e archi (node, edge) hanno il campo next
Codice: |
int remove_edge (graph_t * g, int n1, int n2)
{
node_t *pn;
edge_t *prev;
edge_t *succ;
edge_t *pa;
int tmp,nn1,nn2,i;
... ... ...
/*qui faccio controlli parametri, e metto nn1= min(n1,n2), nn2=max(n1,n2)*/
... ... ...
do/*ciclo per elim le 2 adiacenze*/
{
while (!(pn->label == nn1))
{
pn = pn->next;
}/*ora pn punta a nn1 in nodes*/
pa = pn->adj;
prev = pa;
succ = pa->next;
if(pn->adj->label == nn2)/*se è il primo el della lista*/
{
pn->adj = succ;
free(pa);
}
else
{
while(!(pa->label == nn2))
{
prev = pa;
pa = pa->next;
succ = pa->next;
}/*ora pa punta a nn2 in nodes->adj[nn1]*/
prev->next = succ;
free(pa);
}
pn->degree --;
g->e_size--;
tmp++;
i = nn1;
nn1 = nn2;
nn2 = i;
}
while(tmp!=0 );
if(tmp != 0)
tmp = -1;
return tmp;
}
|
|
|
Top |
|
 |
SverX Supervisor Macchinisti


Registrato: 25/03/02 12:16 Messaggi: 11809 Residenza: Tokelau
|
Inviato: 03 Apr 2008 10:29 Oggetto: |
|
|
scusa la domanda che può suonare stupida... ma se deallochi, ad esempio, l'unico arco che va dal nodo A al nodo B, in un semplicissimo grafo del tipo
ti perdi mica il riferimento a B ?
(mi rendo conto di non ricordarmi cosa sono le liste di adiacenza però... shame on me... ) |
|
Top |
|
 |
saetta Eroe in grazia degli dei

Registrato: 25/02/08 11:52 Messaggi: 129
|
Inviato: 03 Apr 2008 11:49 Oggetto: |
|
|
No
non perdo il riferimento a B perchè i nodi sono contenuti in una lista di node_t chiamata"nodes", campo della struttura grafo.
dunque con g->nodes->next posso scorrerla e trovare B (quando g->nodes->label = B->label)
la mia lista di adiacenza consiste in una lista o vettore di struct nodes_t (int label, node_t *next, edge_t *adj ....)
dove nel campo adj di tali nodi è "attaccata" la lista degli archi(edge_t) adiacenti al nodo.
Non so se sono stata chiara... |
|
Top |
|
 |
SverX Supervisor Macchinisti


Registrato: 25/03/02 12:16 Messaggi: 11809 Residenza: Tokelau
|
Inviato: 03 Apr 2008 12:11 Oggetto: |
|
|
saetta ha scritto: | la mia lista di adiacenza consiste in una lista o vettore di struct nodes_t (int label, node_t *next, edge_t *adj ....)
dove nel campo adj di tali nodi è "attaccata" la lista degli archi(edge_t) adiacenti al nodo.
Non so se sono stata chiara... |
Chiarissima.
Quindi rimuovere un arco, per un nodo specifico, consiste in:
- cercare nella lista dei nodi quello in questione
- scorrere la SUA lista degli archi fino a trovare quello che si deve rimuovere
- rimuoverlo (ovviamente senza fare cadere a pezzi la lista...)
è nella fase della rimozione archi che hai i memory leaks? |
|
Top |
|
 |
saetta Eroe in grazia degli dei

Registrato: 25/02/08 11:52 Messaggi: 129
|
Inviato: 03 Apr 2008 12:19 Oggetto: ohi ohi |
|
|
Ecco non so quale delle tre funzioni fa casino
remove_edge, remove_node o free_graph???
free_graph() usa remove_node()
remove_node() usa remove_edge()
quando un nodo viene cancellato la sua lista di adiacenza viene per intero liberata e vengono cancellati gli archi che lo riguardano nelle liste degli altri nodi
quando un arco viene cancellato la sua lista non cade a pezzi (verificato con stampe)
Mi perdo qualcosa... |
|
Top |
|
 |
SverX Supervisor Macchinisti


Registrato: 25/03/02 12:16 Messaggi: 11809 Residenza: Tokelau
|
Inviato: 03 Apr 2008 15:28 Oggetto: Re: ohi ohi |
|
|
saetta ha scritto: | quando un arco viene cancellato la sua lista non cade a pezzi (verificato con stampe) |
partiamo da qui. Se la funzione di rimozione archi è in grado di cancellare un arco senza problemi in tutti i casi (ad esempio sia che l'arco sia il primo della lista, sia che sia l'ultimo e sia che sia uno 'in mezzo') allora siamo sicuri che la funzione è corretta. A quel punto andiamo a vedere se la procedura di rimozione nodi funziona anche lei in tutti i casi.
Hai la prova che la rimozione degli archi funzioni in ogni caso? Se, mettiamo, dal nodo A ci sono archi verso i nodi B, C e D, la funzione di rimozione archi esegue con successo la cancellazione di uno qualsiasi degli archi lasciando intera la lista con i due archi rimanenti? |
|
Top |
|
 |
saetta Eroe in grazia degli dei

Registrato: 25/02/08 11:52 Messaggi: 129
|
Inviato: 03 Apr 2008 16:07 Oggetto: |
|
|
A giudicare dalle stampe si... tutto ok, nodi e archi ma le stampe non mi mostrano la memoria... |
|
Top |
|
 |
SverX Supervisor Macchinisti


Registrato: 25/03/02 12:16 Messaggi: 11809 Residenza: Tokelau
|
Inviato: 03 Apr 2008 16:38 Oggetto: |
|
|
saetta ha scritto: | A giudicare dalle stampe si... tutto ok, nodi e archi ma le stampe non mi mostrano la memoria... |
prova a sostituire alle malloc() e alle free() due funzioni tue, tipo my_malloc() e my_free() che, dopo aver allocato e prima di disallocare, stampino il valore del puntatore, ad esempio in esadecimale.
così puoi controllare le allocazioni e le deallocazioni... |
|
Top |
|
 |
saetta Eroe in grazia degli dei

Registrato: 25/02/08 11:52 Messaggi: 129
|
Inviato: 03 Apr 2008 22:40 Oggetto: |
|
|
ma il puntatore su cui ho chiamato la free() punta ancora a quella memoria (ormai libera) e non a NULL!!! Se non gli assegno qualcos'altro...il valore dovrebbe essere lo stesso...
Dunque vedo se ciò che alloco viene anche deallocato...
Provo e ti faccio sapere!
grazie. |
|
Top |
|
 |
saetta Eroe in grazia degli dei

Registrato: 25/02/08 11:52 Messaggi: 129
|
Inviato: 04 Apr 2008 14:03 Oggetto: Mi vergogno come una spia... |
|
|
Ok FUNZIONA!!! (e non ci sono memory leaks)
Mi vergogno a dirlo ... dentro ad una funzione creo un grafo a partire da quello in input... all'uscita della funzione non lo deallocavo...
Mi batto nel muro da sola o ci pensate voi?
Grazie 1000 SverX! |
|
Top |
|
 |
SverX Supervisor Macchinisti


Registrato: 25/03/02 12:16 Messaggi: 11809 Residenza: Tokelau
|
Inviato: 04 Apr 2008 17:21 Oggetto: |
|
|
Sono lieto che il problema sia risolto
 |
|
Top |
|
 |
|