J'essaie de mettre en œuvre une structure de données trie pour vérifier l'orthographe d'un fichier texte donné. Actuellement, il semble fonctionner pour quelques mots dans le fichier, puis il atteint un défaut de seg. J'ai essayé de déboguer pour trouver le coupable, mais tout ce que j'ai trouvé, c'est que la valeur de "lettre" conserve des valeurs négatives apparemment aléatoires (elle devrait être comprise entre 1 et 27, inclusivement). Normalement, le problème de la faute seg apparaît presque instantanément après le démarrage du programme, donc je ne sais pas pourquoi le problème surgit au milieu du programme.Erreur de segmentation dans l'implémentation de Trie dans C
/**
* Implements a dictionary's functionality.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "dictionary.h"
//create global root node
Trienode *root;
//create word counter for size() function
unsigned int wordcount = 0;
//creates an empty node
Trienode * newnode()
{
Trienode *nnode = NULL;
nnode = (Trienode *)malloc(sizeof(Trienode));
//initialize new node with null pointers and values
nnode -> parent = NULL;
for(int i = 0; i < 27; i++)
{
nnode -> children[i] = NULL;
}
return nnode;
}
void cleartrie(Trienode *head)
{
//if child node exists, free it, else continue with next iteration in for loop
if(head)
{
for(int i = 0; i < 27; i++)
{
cleartrie(head -> children[i]);
}
free(head);
head = NULL;
}
}
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char *word)
{
int i = 0;
int letter;
Trienode *head = root;
while(word[i] != '\0')
{
if(isalpha(word[i]))
{
letter = word[i] - 'a';
}
else //it must be an apostrophe
{
letter = word[i] - 13;
}
if(!(head -> children[letter]))
{
return false;
}
else //a pointer must exist
{
head = head -> children[letter];
}
i++;
}
return true;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char *dictionary)
{
//open file
FILE *infile = fopen(dictionary, "r");
Trienode *parnode; //parent node
root = newnode();
Trienode *curnode = root; //current node
int letter = 0;
//while not end of file, read words
while(fgetc(infile) != EOF)
{
//while not end of word, read letters
for(;;)
{
int c;
//read current letter in file
c = fgetc(infile);
//convert input char to corresponding array location (a - z = 0-25, apostrophe = 26)
if(isalpha(c))
{
letter = c - 'a';
}
else if (c == '\'')
{
letter = c - 13;
}
//if end of string, exit loop
else if (c == '\0')
{
//end of word, so endofstring = true
wordcount++;
break;
}
//move to next letter if not either apostrophe or alphabetical
else
{
break;
}
//if pointer to letter of word doesn't exist, create new node
if(curnode -> children[letter] == NULL)
{
curnode -> children[letter] = newnode();
}
//child node is the new current node
parnode = curnode;
curnode = curnode -> children[letter];
curnode -> parent = parnode;
}
//return to root node
curnode = root;
}
fclose(infile);
return true;
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
return wordcount;
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
cleartrie(root);
if (root == NULL)
{
return true;
}
return false;
}
Désolé pour le mur du texte, mais pour la plus grande partie est juste là pour contexte (je espère). L'erreur de seg se produit sur la ligne if (! (Head -> children [letter])) de la fonction d'aide de vérification.
Merci d'avance!
Je ne vois pas ce qu'est un Trienode dans votre code. Est-ce une structure? – Jerinaw
Avez-vous utilisé un débogueur? À quels points de votre code exactement l'erreur set se produit (le débogueur devrait vous le dire)? Où voyez-vous que la valeur de 'letter' va de travers? Comme il s'agit d'une liste partielle de codes (et je ne suggérerais pas de mettre tout votre code sans réduire le problème), il est difficile de dire où le problème est juste de le "regarder". Faites plus de débogage et affinez-le. – lurker
Utilisez valgrind. Il vous dira où sont vos problèmes. –