|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Apr 2006
Città: Ilê-de-France
Messaggi: 319
|
[C] deallocazione di un albero binario
Salve ragazzi, ho un piccolo problema, non riesco a capire come deallocare tutti i nodi di un albero
![]() mi spiego meglio ho un albero binario, e alla chiusura del programma lo devo deallocare, quindi io ho pensato di fare una funzione ricorsiva che a partire da ogni nodo dealloca prima quelli alla sinistra, poi quelli alla destra e infine il nodo, ma pare non funzionare perché in esecuzione mi ritorna Codice:
albero(302) malloc: *** error for object 0x1001000a8: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug Dealloco...Abort trap ![]() l'albero è strutturato con in questo modo Codice:
typedef struct nodoABR { tipobaseABR info; /* tipo di informazioni contenute nel nodo*/ struct nodoABR *leftchild,*rightchild; } *abr; Codice:
void DeallocaABR(abr *p) { if(EmptyABR(*p)) /* se il nodo non ha figli lo dealloco direttamente */ free(p); else /* altrimenti vado a sinistra poi a destra e infine lo dealloco */ { DeallocaABR(&(*p)->leftchild); DeallocaABR(&(*p)->rightchild); free(p); } }
__________________
There is no cloud, it's just someone else computer Ultima modifica di <Gabrik> : 16-06-2011 alle 11:58. |
![]() |
![]() |
![]() |
#2 |
Junior Member
Iscritto dal: Oct 2010
Messaggi: 16
|
penso che il problema risieda nel fatto che tu disallocando un nodo qualsiasi(e i suoi figli) quando vai a disallocare il padre, riprovi a disallocare anche il figlio e questo ti dà errore
infatti dice errore: il puntatore che si sta deallocando (freed) non è allocato, perchè lo potresti aver deallocato poco prima! una soluzione potrebbe essere per ogni nodo deallocare i figli ma non il nodo stesso, tranne che per la radice, magari introducendo un puntatore al nodo padre o una variabile su cui controlli che il nodo sia radice o meno |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Oct 2004
Messaggi: 1945
|
prova una soluzione del genere
Codice:
dealloca_albero(nodo n){ if n == NULL return; nodo *l = n->left nodo *r = n->right free(n) if(l != NULL) dealloca_albero(l) if(r != NULL) dealloca_albero(r) } edit: volendo infatti potresti omettere i controlli tipo if l != NULL e r != NULL dato che appena richiamata ricorsivamente la funzione effettua il controllo, ma in termini di prestazioni è molto meno costoso un controllo che una chiamata ricorsiva Ultima modifica di clockover : 16-06-2011 alle 12:36. |
![]() |
![]() |
![]() |
#4 | ||
Senior Member
Iscritto dal: Apr 2006
Città: Ilê-de-France
Messaggi: 319
|
Quote:
![]() il bello è che dà problemi anche se l'albero è formato dalla sola radice Quote:
comunque lui prende *p sempre come se fosse una radice, controlla se ha figli e poi fà quello che deve fare, piuttosto credo di aver fatto casino sui puntatori quando faccio &(*p)->leftchild e &(*p)->rightchild
__________________
There is no cloud, it's just someone else computer |
||
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Apr 2006
Città: Ilê-de-France
Messaggi: 319
|
Quote:
![]() edit: funzia ![]() edit2: confermo avevo fatto casino con i puntatori infatti modificando la funzione così Codice:
void DeallocaABR(abr a) { if(EmptyABR(a)) free(a); else { DeallocaABR(a->leftchild); DeallocaABR(a->rightchild); free(a); } } ![]()
__________________
There is no cloud, it's just someone else computer Ultima modifica di <Gabrik> : 16-06-2011 alle 12:54. |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 10:37.