I'm implementing a trie data structure in C for words in a large dictionary. The dictionary contains strings in the following format:
abacus
babble
cabal
....
I define and allocate memory for the trie outside of load
function. load
reads each word from the dictionary and insert each character into a position of array children[27]
inside each node
. Indices 0 to 25 are for characters a
to z
and apostrophe character '
at position 26.
The problem is I don't know if I should create and allocate memory for the trie top level inside or outside the calling function. I will be freeing the memory using another function unload
after I finished using the trie. I cannot modify the main
function so I'm not sure there will be no memory leak after I'm finished.
Here is the code:
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// trie data structure for 26 letters and apostrophe
typedef struct node
{
bool is_word;
struct node *children[27];
} node;
// allocate memory for trie top level and set them to 0
node *root = calloc(1, sizeof(node));
// loads dictionary into memory, return true if successful
bool load(const char *dictionary)
{
// open input file
FILE *fp = fopen(dictionary, "r");
if (fp == NULL)
return false;
int p; // trie index position
char c; // current char
// scan dictionary word by word
while (fscanf(fp, "%s", word) != EOF)
{
// set head pointer to point to root
node *head = root;
// loop through current word
for (int i = 0; i < strlen(word); i++)
{
c = word[i];
// ASCII to alphabet position, apostrophe last index
if (isalpha(c))
p = c - 'a';
else if (c == '\'')
p = 26;
// allocate memory and point head to new node
if (head->children[p] == NULL)
{
head->children[p] = calloc(1, sizeof(node));
head = head->children[p];
}
// otherwise point head to children
else if (head->children[p] != NULL)
head = head->children[p];
}
// complete word, set flag to true
head->is_word = true;
}
// finished
fclose(fp);
return true;
}