Dicitonnaire en c
luck22
Messages postés
11
Date d'inscription
Statut
Membre
Dernière intervention
-
loupius Messages postés 697 Date d'inscription Statut Membre Dernière intervention -
loupius Messages postés 697 Date d'inscription Statut Membre Dernière intervention -
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
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.
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.
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
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"
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
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
voila c 'est le code de la fonction
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 :
sinon tous les cas sont traités je pense
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:
Bonne réflexion.
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.
Il suffit ainsi de modifier la fin de la fonction:
Bonne continuation.
... 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.
Tu peux donner l'autre fonction, sans oublier d'utiliser les balises 'code' sises à droite de la balise 'souligné'.