Have been trying to debug this for days and eventually came down to the following problem: When running an example test(lalaland.txt) the misspelled words are fine up until the program abruptly stops(in this case between line 4311 and 4328 of the given text). The error is a segmentation fault, have researched a lot, but still can't find what I did wrong. Here's my code:
// Implements a dictionary's functionality
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dictionary.h"
// Represents number of children for each node in a trie
#define N 27
// Represents a node in a trie
typedef struct node
{
bool is_word;
struct node *children[N];
}
node;
// Represents a trie
node *root;
// Word counter variable
int counter = 0;
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// Initialize trie
root = malloc(sizeof(node));
if (root == NULL)
{
return false;
}
root->is_word = false;
for (int i = 0; i < N; i++)
{
root->children[i] = NULL;
}
// Open dictionary
FILE *file = fopen(dictionary, "r");
if (file == NULL)
{
unload();
return false;
}
node *dict = root;
// Insert words into trie
while (true)
{
char word = fgetc(file);
if(word == EOF)
{
break;
}
if(word != '\n')
{
int index = (word >= 'a' && word <= 'z') ? word - 'a' : 26;
if (dict->children[index] == NULL)
{
dict->children[index] = malloc(sizeof(node));
dict->children[index]->is_word = false;
dict = dict->children[index];
for (int j = 0; j < N; j++)
{
dict->children[j] = NULL;
}
}else{
dict = dict->children[index];
}
}else{
dict->is_word = true;
dict = root;
counter++;
}
}
// Close dictionary
fclose(file);
// Indicate success
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
if (!counter)
{
return counter;
}
return 0;
}
// Returns true if word is in dictionary else false
bool check(const char *word)
{
node *dict = root;
for (int i = 0; i < strlen(word); i++)
{
int index = 0;
if (word[i] == '\'')
{
index = 26;
}else{
if (word[i] >= 'a' && word[i] <= 'z')
{
index = word[i] - 'a';
}else{
if(word[i] >= 'A' && word[i] <= 'Z'){
index = word[i] - 'A';
}else{
return false;
}
}
}
if (dict->children[index] != NULL)
{
dict = dict->children[index];
}else{
return false;
}
}
return dict->is_word;
}
//stores current node
node *curr;
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
if (root == NULL)
{
return false;
}
node* child[N];
//initializing children
for(int i = 0; i < N; i++)
{
child[i] = curr->children[i];
}
//remove current node
free(curr);
//recursion over all children
for(int i = 0; i < 27; i++)
{
if(child[i] != NULL)
{
curr = child[i];
}
unload();
}
return true;
}