#1 Le 01/12/2013, à 21:42
- shoot76
Segmentation Fault en C -- Arbre lexicographique
Bonjour à tous
Dans le cadre d'un projet de fin de semestre, nous devons développer un correcteur orthographique en C, celui-ci possédant un fichier en entrée avec un nombre conséquent de mots.
Nous bloquons tous (dans mon groupe) sur cette erreur de segmentation fault malgré nos tentatives de reflexion ainsi que l'aide de gdb indiquant une erreur à la ligne 43 :
if (mot[0] > (*arbre)->c)
return inserer(mot,&((*arbre)->fd));
Je fais donc appel aux connaisseurs de C, non pas pour me donner une réponse (ça serait trop simple) mais surtout pour m'expliquer ce qui peut causer une telle erreur de façon à ce qu'on puisse y faire plus attention notamment lors de son utilisation.
Je vous fournis tout le code pour illustrer mon propos :
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct tnoeud
{
char c; // le caractere du mot
unsigned long n; // #occurences du mot
struct tnoeud *fa,*fd; // pointeur sur fils aine / freres droits
} tnoeud;
typedef struct tnoeud * tarbre;
tarbre arbre = NULL;
char mot[256];
unsigned char i = 0;
unsigned long nbmots = 0;
// cree un nouvel arbre et initialise ses champs
tarbre new(char c, ulong n, struct tnoeud *fa, struct tnoeud *fd)
{
tarbre aux;
aux = (tarbre) malloc (sizeof(tnoeud));
aux->c = c;
aux->n = n;
aux->fa = fa;
aux->fd = fd;
return aux;
}
//insere un mot dans l'arbre et renvoie son # d'occurences
unsigned long inserer(char * mot, tarbre *arbre)
{
if ((*arbre) == NULL) // on cree un noeud, l'arbre est vide
{
(*arbre) = new(mot[0], (strlen(mot) == 1), NULL, NULL);
if (strlen(mot) == 1)
return 1;
else
return inserer(++mot,&((*arbre)->fa));
}
else
{
if (mot[0] > (*arbre)->c) // on avance dans la liste des freres
return inserer(mot,&((*arbre)->fd));
else
if (mot[0] == (*arbre)->c) // on a trouve la lettre
if (strlen(mot) == 1)
return ++(*arbre)->n;
else
return inserer(++mot,&((*arbre)->fa));
else // lettre nouvelle, insere dans la liste des freres
{
tarbre aux = new(mot[0], (strlen(mot) == 1), NULL, (*arbre));
(*arbre) = aux;
if (strlen(mot) == 1)
return 1;
else
return inserer(++mot,&((*arbre)->fa));
}
}
}
void afficher(tarbre arbre)
{
if (arbre != NULL)
{
mot[i] = arbre->c;
if (arbre->n > 0)
printf("%s:%lu\n",mot,arbre->n);
i++;
afficher(arbre->fa);
mot[i] = ' ';
i--;
afficher(arbre->fd);
}
}
int main(int argc, char *argv[])
{
printf("Debut de l'analyse\n");
char *mot = "chien";
char *mot2 = "chat";
tarbre lex;
inserer(mot,&lex);
int nbmots = 0;
printf("Fin de l'analyse: %d mots\n\n",nbmots);
afficher(arbre);
return 0;
}
Je vous remercie par avance pour votre aide !
Cordialement
~ Data-sientist freelance : https://skulder.fr
Hors ligne
#2 Le 01/12/2013, à 21:53
- Braun
Re : Segmentation Fault en C -- Arbre lexicographique
Bonsoir,
J'avoue ne pas avoir lu ton programme, mais souvent une erreur de segmentation est due à une boucle qui utilise trop de mémoire. En général la raison en est une clause d'échappement inefficace.
Un truc serait peut-être d'ajouter un compteur pour limiter arbitrairement le nombre des passages par ta ligne 43.
Hors ligne
#3 Le 01/12/2013, à 22:38
- telliam
Re : Segmentation Fault en C -- Arbre lexicographique
1er remarque dans le main, assigne null a lex sinon tu px pas prévoir ou tu vas passer. Et compile ton programme avec le flag -Wall et fixe tous les warning
Dernière modification par telliam (Le 01/12/2013, à 22:39)
"- Un intellectuel assis va moins loin qu'un con qui marche."
Maurice Biraud - Un Taxi pour Tobrouk
Michel Audiard
Hors ligne
#4 Le 02/12/2013, à 21:24
- shoot76
Re : Segmentation Fault en C -- Arbre lexicographique
Bonsoir
Déjà merci à vous deux pour vos réponses. On en a calé un bon coup cet après midi avec mon groupe et résolu la plupart des bugs (plein de petites erreurs s'étaient glissées dedans sans causer pour autant de problème de compilation)
Maintenant les mots s'ajoutent à l'arbre, il nous manque juste une procédure afficher pour permettre sa visualisation (je sais, elle est dans mon code, mais elle affiche rien bizarrement...) !
Vraiment merci pour vos indications qui nous ont permis de nous lancer dans la tâche de déboguage de ce code. La prochaine fois, je compilerai régulièrement, ça m'évitera de me prendre la tête pendant 2h pour trouver mes erreurs ^^
Notre projet avance bien plus vite maintenant qu'on a cette structure fonctionnelle.
Bonne soirée !
~ Data-sientist freelance : https://skulder.fr
Hors ligne
#5 Le 02/12/2013, à 21:38
- Braun
Re : Segmentation Fault en C -- Arbre lexicographique
Bonsoir,
Toujours dans les lieux communs, tu peux rajouter quelques printf() voire des messages d'erreur aux points stratégiques. E.g.
if (arbre != NULL)
{
mot[i] = arbre->c;
if (arbre->n > 0)
printf("%s:%lu\n",mot,arbre->n);
else printf("Négatif") ;
i++;
afficher(arbre->fa);
mot[i] = ' ';
i--;
afficher(arbre->fd);
}
else printf("C'est nul") ;
ou que sais-je.
Hors ligne
#6 Le 02/12/2013, à 22:28
- telliam
Re : Segmentation Fault en C -- Arbre lexicographique
Bonsoir
Déjà merci à vous deux pour vos réponses. On en a calé un bon coup cet après midi avec mon groupe et résolu la plupart des bugs (plein de petites erreurs s'étaient glissées dedans sans causer pour autant de problème de compilation)
Maintenant les mots s'ajoutent à l'arbre, il nous manque juste une procédure afficher pour permettre sa visualisation (je sais, elle est dans mon code, mais elle affiche rien bizarrement...) !
Vraiment merci pour vos indications qui nous ont permis de nous lancer dans la tâche de déboguage de ce code. La prochaine fois, je compilerai régulièrement, ça m'évitera de me prendre la tête pendant 2h pour trouver mes erreurs ^^
Notre projet avance bien plus vite maintenant qu'on a cette structure fonctionnelle.
Bonne soirée !
redonne ton code si tu vx qu'on t'aide pour l'affichage, mais il n'y a rien de magique, si il n'y a rien qui s'affiche il y a des chances que tu rentres pas dans la portion de code que tu penses
"- Un intellectuel assis va moins loin qu'un con qui marche."
Maurice Biraud - Un Taxi pour Tobrouk
Michel Audiard
Hors ligne
#7 Le 03/12/2013, à 10:45
- shoot76
Re : Segmentation Fault en C -- Arbre lexicographique
Je vous envoie ça ce soir, je dois récupérer le code sur le réseau de mon école d'abord.
Pour la fonction afficher on a juste fait un truc très simple du genre :
void afficher (tarbre arbre) {
if (arbre != NULL) {
printf("%c",arbre->c);
afficher(arbre->fa);
afficher(arbre->fg);
}
}
Mais je vous envoie tout ça ce soir, l'affichage reste surtout un moyen de valider la bonne architecture de notre arbre. Je dois me coller aux tests CUnit également pour vérifier qu'il ne plante pas dans certains cas.
En tout cas merci à vous
Dernière modification par shoot76 (Le 03/12/2013, à 10:45)
~ Data-sientist freelance : https://skulder.fr
Hors ligne
#8 Le 21/02/2014, à 22:10
- TuringMachine
Re : Segmentation Fault en C -- Arbre lexicographique
Bonsoir,
Il faudrait peut-être citer la source de votre programme que vous avez récupéré sur un site public sans mentionner son auteur pour commencer. Et l'auteur vous aurait fait remarquer qu'outre s'approprier le travail d'autrui, utiliser des pointeurs sans allocations c'est mal:
char *mot = "chien";
char *mot2 = "chat";
Cordialement.
Dernière modification par TuringMachine (Le 21/02/2014, à 22:11)
Hors ligne