Newsgroup: it.comp.lang.c
Titolo: problema con albero binario di ricerca

Sto provando le funzioni fsearch e tfind definite in <search.h> . So che 
non sono funzioni ansi C99 ma posix, tuttavia spero di non essere OT.
Il mio codice fa
conn2 = tsearch ((void*) conn, &tree, compare);
dove conn e conn2 sono due puntatori a una struttura definita da me e 
tree č un puntatore void inizialmente posto a NULL perché l'albero č vuoto.
Bene, dopo questa istruzione io mi ritrovo che tree e conn2 puntano 
entrambi allo stesso indirizzo, che perň non č lo stesso di conn. Il 
problema nasce quando poi cerco di riestrarre l'elemento inserito, 
perché tfind mi ritorna l'idirizzo di conn2 e non quello di conn e da lě 
al segfault il passo č breve.
Ora, non riesco a capire se sono io che sbaglio ad usare tsearch e tfind 
o se quello che mi viene ritornato deve essere manipolato in qualche 
modo. Penso che conn2 sia un wrapper del mio oggetto, ma non so come 
accederci per recuperare l'informazione.
Qualcuno puň aiutarmi? O qualcuno di voi ha un programma di esempio che 
usa tale funzione?
Grazie,
Ottavio

 Ottavio
Quello che descrivi non mi è mai successo, almeno che io ricordi...
Provo a mandarti due righe di esempio e dimmi se hai qualche
illuminazione - altrimenti prova a postare il codice!
#include <stdio.h>
#include <stdlib.h>
#include <search.h>
typedef struct b_s {
    int a, b;
} b_st;
int compare(const void *p1, const void *p2)
{
    int q1, q2;
    q1 = ((b_st*)p1)->a+((b_st*)p1)->b;
    q2 = ((b_st*)p2)->a+((b_st*)p2)->b;
    if (q1>q2) return 1;
    else if (q1<q2) return -1;
    else return 0;
}
int main()
{
    b_st *b1, *b2;
    b_st *broot, *boh;
    b1 = malloc(sizeof(*b1));
    b2 = malloc(sizeof(*b2));
    b1->a = b1->b = 1;
    b2->a = b2->b = 2;
    printf("%p %p\n", (void*)b1, (void*)b2);
    broot = NULL;
    boh = tsearch(b1, (void**)&broot, compare);
    printf("%p %p\n", (void*)boh, (void*)broot);
    boh = tfind(b1, (void**)&broot, compare);
    printf("%p\n", (void*)boh);
    boh = tfind(b2, (void**)&broot, compare);
    printf("%p\n", (void*)boh);
    free(b2);
    free(b1);
    return EXIT_SUCCESS;
}

 illuminazione - altrimenti prova a postare il codice!
grazie della celerissima risposta, ho modificato un attimo il tuo 
programma per farti vedere il problema
#include <stdio.h>
#include <stdlib.h>
#include <search.h>
typedef struct b_s {
     int a, b;
} b_st;
int compare(const void *p1, const void *p2)
{
     int q1, q2;
     q1 = ((b_st*)p1)->a+((b_st*)p1)->b;
     q2 = ((b_st*)p2)->a+((b_st*)p2)->b;
     if (q1>q2) return 1;
     else if (q1<q2) return -1;
     else return 0;
}
int main()
{
     b_st *b1, *b2;
     b_st *broot, *boh;
     b1 = malloc(sizeof(*b1));
     b2 = malloc(sizeof(*b2));
     b1->a = b1->b = 1;
     b2->a = b2->b = 2;
     printf("%p %p\n", (void*)b1, (void*)b2);
     broot = NULL;
     boh = tsearch(b1, (void**)&broot, compare);
     printf("tsearch: boh %p b1 %p broot %p\n", (void*)boh, (void*) b1, 
(void*)broot);
     fprintf (stdout, "boh->a %d\n", boh->a);
     boh = tfind(b1, (void**)&broot, compare);
     printf("%p\n", (void*)boh);
     boh = tfind(b2, (void**)&broot, compare);
     printf("%p\n", (void*)boh);
     free(b2);
     free(b1);
     return EXIT_SUCCESS;
}
Il cui output è
ottavio@debian2:/tmp$ ./tt
0x7d1010 0x7d1030
tsearch: boh 0x7d1050 b1 0x7d1010 broot 0x7d1050
boh->a 8196112
0x7d1050
(nil)
Quindi il programma mettere la radice in 0x7d1050, il primo elemento che 
vuoi aggiungere sta in 0x7d1010 e il puntatore ritornato è quello che 
penso sia un wrapper e coincide con la radice dell'albero a che non è 
l'indirizzo del dato inserito.
L'output del primo tfind è sempre 0x7d1050 e non 0x7d1010, quindi anche 
se il printf è messo (per pigrizia) prima del tfind il risultato non 
cambia perché boh ha sempre lo stesso valore (lo vedi dal printf 
successivo) e boh->a è completamente sbagliato.
Io vorrei riaccedere col puntatore ritornato dalla find al campo a di 
b1. Come posso fare?

 successivo) e boh->a è completamente sbagliato.
Ah ok, ho capito il tuo dubbio!
No, per accedere ad a, l'operazione è diversa. Dentro l'albero vengono
memorizzati (e quindi restituiti) solo i puntatori agli oggetti
inseriti. Quindi per accedere ad a, nel nostro caso:
(*(b_st**)boh)->a
ti darà il risultato giusto.


grazie.