Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 01/12/2013, à 22:42

shoot76

Segmentation Fault en C -- Arbre lexicographique

Bonjour à tous big_smile

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, à 22: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, à 23: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, à 23: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, à 22:24

shoot76

Re : Segmentation Fault en C -- Arbre lexicographique

Bonsoir smile

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 ! big_smile


~ Data-sientist freelance : https://skulder.fr

Hors ligne

#5 Le 02/12/2013, à 22: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, à 23:28

telliam

Re : Segmentation Fault en C -- Arbre lexicographique

shoot76 a écrit :

Bonsoir smile

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 ! big_smile

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, à 11: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 smile

Dernière modification par shoot76 (Le 03/12/2013, à 11:45)


~ Data-sientist freelance : https://skulder.fr

Hors ligne

#8 Le 21/02/2014, à 23: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, à 23:11)

Hors ligne