Salve a tutti, sono qui con uno dei miei soliti dilemmi...
Allora, implementando un albero binario bilanciato
avevo scritto una funzione che mi rimuovesse un nodo, memorizzasse
il suo indirizzo in un puntatore a puntatore passato come parametro
e restituisse il suo nodo sinistro. Il problema è che questa funzione
mi causava un bel SIGSEGV al suo ritorno poichè utilizzavo direttamente il
valore restituito. Ora io ho risolto però vorrei capire se questo
è un bug del mio compilatore o se è una cosa normale.
Faccio un esempio per spiegare. Ecco una funzione che fa piu
o meno quello che faceva la mia:
Ok ora la funzione main che utilizza la funzione definita,codice:#include <stdlib.h> struct node { struct node *left, *right; void *data; }; /* Salva un nodo in *node e ne restituisce un'altro */ struct node *sigsegv(struct node **node) { struct node *__r; struct node *__n; /* Creo due nodi sullo heap */ __n = malloc(sizeof(struct node)); __n->left = NULL; __n->right = NULL; __n->data = NULL; __r = malloc(sizeof(struct node)); __r->left = NULL; __r->right = NULL; __r->data = NULL; /* Mette l'indirizzo di __n in *node */ *node = __n; /* Restituisce __r */ return __r; }
occhio alla chiamata:
Esecuzione:codice:int main( ) { struct node *n = NULL; /*** In una chiamata alloca n e setta n->right ***/ n->right = sigsegv(&n); return 0; }
E subito il debugger:codice:$ ./a.out Segmentation fault
In parole povere non posso fare n->right = sigsevg(&n)codice:$ gdb a.out GNU gdb 6.3 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. ... (gdb) break main Breakpoint 1 at 0x80483ee: file testptr.c, line 28. (gdb) run Starting program: /home/._/a.out (gdb) step 30 n->right = sigsegv(&n); (gdb) step sigsegv (node=0xbfa40b50) at testptr.c:14 14 __n = malloc(sizeof(struct node)); (gdb) step 15 __n->right = NULL; (gdb) step 16 __n->data = NULL; (gdb) step 18 __r = malloc(sizeof(struct node)); (gdb) step 19 __r->right = NULL; (gdb) step 20 __r->data = NULL; (gdb) step 22 *node = __n; (gdb) step 23 return __r; (gdb) print __r $1 = (struct node *) 0x804a060 (gdb) print *__r $2 = {right = 0x0, data = 0x0} (gdb) print __n $3 = (struct node *) 0x804a050 (gdb) print *__n $4 = {right = 0x0, data = 0x0} (gdb) step 24 } (gdb) step Program received signal SIGSEGV, Segmentation fault. 0x08048407 in main () at testptr.c:30 30 n->right = sigsegv(&n); (gdb)
perchè al momento in cui la funzione ritorna n non è inizializzato.
Ma se viene impostato dentro alla fnzione!?
Ad esempio se io faccio
Funziona perfettamente. Qualcuno mi spiega perchè succede questo!?codice:... struct node *n = NULL, *right = NULL; right = sigsegv(&n); n->right = right; ...
Grazie in anticipo! Christian.