Dicitonnaire en c
luck22
Messages postés
13
Statut
Membre
-
loupius Messages postés 789 Statut Membre -
loupius Messages postés 789 Statut Membre -
Bonjour tout le monde,
je veux coder un dicitonnaire en c en utilisant un arbre lexicographique alors j'ai défini ma strucutre comme suit :
typedef struct NOEUD
{
char lettre;
struct NOEUD *frere, *fils;
} Noeud, * Dictionnaire;
et pour ma fonction qui insére un caractere dans le dicitonnaire elle débute comme ça :
Noeud * inserer_caractere(Noeud * position , char c)
{Noeud * temp = position
Noeud * nouvelElement;
if (c < temp->lettre)
{nouvelElement = (Noeud*)malloc(sizeof(Noeud));
nouvelElement->lettre = c;
nouvelElement->frere = temp;
nouvelElement->fils = NULL;
return nouvelElement;
} etc
à l'éxécution j'ai une erreur de segmentation , et lorsque je debuggue avec (gdb)
il m'indique que c'est du à la ligne( if (c < temp->lettre) )
et je comprends pas pourquoi cette ligne provoque une erreur.
Je vous remercie
je veux coder un dicitonnaire en c en utilisant un arbre lexicographique alors j'ai défini ma strucutre comme suit :
typedef struct NOEUD
{
char lettre;
struct NOEUD *frere, *fils;
} Noeud, * Dictionnaire;
et pour ma fonction qui insére un caractere dans le dicitonnaire elle débute comme ça :
Noeud * inserer_caractere(Noeud * position , char c)
{Noeud * temp = position
Noeud * nouvelElement;
if (c < temp->lettre)
{nouvelElement = (Noeud*)malloc(sizeof(Noeud));
nouvelElement->lettre = c;
nouvelElement->frere = temp;
nouvelElement->fils = NULL;
return nouvelElement;
} etc
à l'éxécution j'ai une erreur de segmentation , et lorsque je debuggue avec (gdb)
il m'indique que c'est du à la ligne( if (c < temp->lettre) )
et je comprends pas pourquoi cette ligne provoque une erreur.
Je vous remercie
Configuration: Windows Vista Firefox 3.5.6
7 réponses
-
une erreur de segmentation, c'est une erreur mémoire. Ceci signifie qu'il doit y avoir un souci avec le pointeur que tu utilises (temp). Le pointeur ne pointe pas vers une zone valide. L'erreur se déclenche à cet endroit, car c'est là que ton pointeur mal initialisé est utilisé. Mais la véritable erreur logique est ailleurs.
Quel est le pointeur qui pose problème ? réponse : temp
D'où vient temp ? réponse : il vient de là : Noeud * temp = position
d'où vient position ? c'est un paramètre de ta fonction. Il faut donc chercher là où tu appelles ta fonction. Le pointeur que tu lui donnes en paramètre est probablement mauvais. -
oui tout à fait le paramétre "position" est un pointeur sur la tete de la liste et voici la fontion inser_mot qui fait appel à inserer_caractere
Noeud * inserer_mot(Noeud * d , char * chaine) { // Noeud * temp; //Noeud * premier; Noeud * pere=d,* temp , *premier; int n,j,t; j=0; temp=inserer_caractere(d , chaine[0]); if((temp->lettre) < (d->lettre)) // dans ce cas on a une nvlle teste de liste d=temp; pere=temp; j++; while ((pere->fils != NULL) && (j<strlen(chaine))) { premier = pere->fils; temp = inserer_caractere( premier , chaine[j]); if (temp->lettre < premier->lettre) pere->fils =temp; pere=temp; j++; } t=j; for(j=t ; j<strlen(chaine); j++) {pere->fils = nouvelleCellule(chaine[j]); pere= pere->fils; } pere->fils = nouvelleCellule('#'); return d; } -
Ce qui me semble curieux:
temp = inserer_caractere(d, chaine[0]);
if ((temp->lettre) < (d->lettre)) // dans ce cas on a une nvlle teste de liste
Ce que nous savons c'est ce que retourne 'inserer_caractere' lorsque c'est une nouvelle tête de liste, ce que nous ne savons pas c'est ce que nous retourne 'inserer_caractere' dans l'autre cas. En effet, dans ce cas, qu'est-ce qui nous dit que le test est faux ?
Ton code est difficile à suivre; pourquoi mettre 'j=0' et 'j++', il vaut mieux mettre 'j=1', pourquoi mettre 'pere=d', c'est inutile.
Le plus sûr moyen de trouver ton erreur est de suivre les adresses de tes pointeurs, en espérant que ça plante assez vite ;-)
Bonne réflexion. -
salut
pour temp = inserer_caractere(d, chaine[0]);
if ((temp->lettre) < (d->lettre))
la en fait on regarder le racine du mot existe deja dans le dictionnaire si oui on change la tete de la liste c'est pour cela QU'ON INCRÉMENTE J CELA SIGNIFIE QU4IL Y A DEJA DES MOTS KI ONT la meme racine donc inutile de réinsérer le debut du mot qui existe deja -
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question -
Le code suivant:
Noeud * pere=d,* temp , *premier; j=0; temp=inserer_caractere(d , chaine[0]); if((temp->lettre)<(d->lettre)) // dans ce cas on a une nvlle teste de liste d=temp; pere=temp; j++;est identique à ce code:Noeud *pere, *temp, *premier; temp = inserer_caractere(d, chaine[0]); if((temp->lettre) < (d->lettre)) // dans ce cas on a une nvlle tête de liste d = temp; pere = temp; j = 1;Mais ceci n'est gênant que pour la compréhension. Ce que j'aurais préféré savoir c'était ce que retourne la fonction 'inserer_caractere' quand ce n'est pas une nouvelle tête de liste.-
oui oui ces deux codes sont identiques et pour la fonction "insére_caractere" en fait le pointeur premier pointe toujours sur une tete de liste dans le premier appel de la fonction "insere_caractere"
Noeud *pere, *temp, *premier; temp = inserer_caractere(d, chaine[0]);
la je verifie si la racine du mot existe deja si oui je change ma tete de liste et j'insere les caracteres à partir de cette nouvelle tete de liste
la fonction "insere caractère"soit elle insere un caractere en tete de la liste soit au milieu ou soit enfin d eliste si le caractere n'existait ps au paravant dans le dictionnaire- OUI elle retourne autre chose en fait c'est selon la position ou elle va placer le caractere
Noeud * inserer_caractere(Noeud * position , char c) {Noeud * temp = position Noeud * nouvelElement; if (c < temp->lettre) {nouvelElement = (Noeud*)malloc(sizeof(Noeud)); nouvelElement->lettre = c; nouvelElement->frere = temp; nouvelElement->fils = NULL; return nouvelElement; // si la lettre n'est pas placée au début , soit on va la palcer enfin de liste soit quelque part entre le début et la fin de la liste, // on se déplace alors dans la liste grace au pointeur temp pour savoir la bonne position ou ns devons insérer notre lettre while((temp->frere !=NULL) && ((temp->frere->lettre )<= c)) temp=temp->frere; if (c<(temp->frere->lettre)) { nouvelElement = (Noeud*)malloc(sizeof(Noeud)); nouvelElement->lettre = c; nouvelElement->frere = temp->frere; nouvelElement->fils = NULL; temp->frere=nouvelElement; return nouvelElement; } if ((temp->frere)==NULL) {nouvelElement = (Noeud*)malloc(sizeof(Noeud)); nouvelElement->lettre = c; nouvelElement->frere = NULL; nouvelElement->fils = NULL; temp->frere=nouvelElement; return nouvelElement; } if (c == temp->lettre) return temp;
voila c 'est le code de la fonction
-
-
Si j'ai bien compris, après remise en forme, on obtient:
Noeud* inserer_caractere(Noeud* position ,char c) { Noeud* temp = position Noeud* nouvelElement; if (c < temp->lettre) { nouvelElement = (Noeud*)malloc(sizeof(Noeud)); nouvelElement->lettre = c; nouvelElement->frere = temp; nouvelElement->fils = NULL; return nouvelElement; } if ((temp->frere)==NULL) { nouvelElement = (Noeud*)malloc(sizeof(Noeud)); nouvelElement->lettre = c; nouvelElement->frere = NULL; nouvelElement->fils = NULL; temp->frere=nouvelElement; return nouvelElement; } if (c == temp->lettre) return temp; }Alors là il y a un problème... il y a des cas où la fonction ne retourne rien... ou plutôt n'importe quoi. Ce n'est peut-être pas la solution à ton problème mais une erreur de ce type entraîne à un moment ou à un autre un 'segment fault'.-
je pense que t'as oublié ce cas ci :
while((temp->frere !=NULL) && ((temp->frere->lettre )<= c)) temp=temp->frere; if (c<(temp->frere->lettre)) { nouvelElement = (Noeud*)malloc(sizeof(Noeud)); nouvelElement->lettre = c; nouvelElement->frere = temp->frere; nouvelElement->fils = NULL; temp->frere=nouvelElement; return nouvelElement; }
sinon tous les cas sont traités je pense
-
-
Ok, j'en avais oublié un bout, donc la fonction est bien:
Noeud* inserer_caractere(Noeud* position ,char c) { Noeud* temp = position Noeud* nouvelElement; if (c < temp->lettre) { nouvelElement = (Noeud*)malloc(sizeof(Noeud)); nouvelElement->lettre = c; nouvelElement->frere = temp; nouvelElement->fils = NULL; return nouvelElement; } while((temp->frere != NULL) && (temp->frere->lettre <= c)) temp=temp->frere; if (c<(temp->frere->lettre)) { nouvelElement = (Noeud*)malloc(sizeof(Noeud)); nouvelElement->lettre = c; nouvelElement->frere = temp->frere; nouvelElement->fils = NULL; temp->frere=nouvelElement; return nouvelElement; } if ((temp->frere)==NULL) { nouvelElement = (Noeud*)malloc(sizeof(Noeud)); nouvelElement->lettre = c; nouvelElement->frere = NULL; nouvelElement->fils = NULL; temp->frere=nouvelElement; return nouvelElement; } // 'Point X' if (c == temp->lettre) return temp; }Il y a donc bien des cas où la fonction ne retourne rien. Quand on arrive au 'Point X' et que 'c' est différent de 'temp->lettre' (ce qui doit bien arriver, sinon pourquoi faire un test? ), d'après toi: que se passe-t-il ?
Bonne réflexion.-
je vous remercie en touc as je vais refléchir à ça et revenir aprés pour vous montrez ce que j'ai eu
- Il suffit ainsi de modifier la fin de la fonction:
... if (c == temp->lettre) return temp; printf ("Passe\n"); }pour savoir si on passe par là; mais quand bien même on n'y passerait jamais il n'est pas correct de ne rien retourner, d'ailleurs le compilateur doit manifester en plaçant un 'warning'.
Bonne continuation.
-