My code is giving all the right answers (lalaland.txt), but valgrind says: ==9947== dictionary.c:69:25: runtime error: index 46 out of bounds for type 'char [46]'
(and I printf the problem - too many letters in word AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHT.)
valgrind continues: dictionary.c:72:29: runtime error: index 46 out of bounds for type 'char [46]'
(and printf continues: too many letters in word AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHT. too many letters in word AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHT. too many letters in word AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHT. too many letters in word AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHT. too many letters in word AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHT. too many letters in word AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHT. too many letters in word AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHT.)
==9947== Invalid read of size 4
my code is:
#include <ctype.h>
#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;
// Function declaration
void freedom(node* trvl);
// Word coounter
int words = 0;
// Loads dictionary into memory
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;
}
// Buffer for a word
char word[LENGTH + 1];
// Insert words into trie
while (fscanf(file, "%s", word) != EOF)
{
// TODO
// create a travelling node to walk the trie
node *trvl = root;
// create index of letter in word
int index;
for (int i = 0; word[i] != '\0'; i++)
{
if (i > 45){printf("too many letters in word %s\n", word);}
index = tolower(word[i]) - 'a';
if (index < 0 || index > 26)
{
index = 26;
}
if (trvl->children[index] == NULL)
{
// create new node
trvl->children[index] = malloc(sizeof(node));
for (int j = 0; j < N; j++)
{
trvl->children[index]->children[j] = NULL;
}
}
// traverse to node
trvl = trvl->children[index];
}
// mark the last node as a word
trvl->is_word = true;
words++;
};
// 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)
{
// TODO
return words;
}
// Returns true if word is in dictionary else false
bool check(const char *word)
{
// TODO
// Variable to hold letter index
int index;
// protect the root, create a travel trie
node *trvl = root;
// Check word letter by letter, comparing to the dictionary
// Moving into the next node each time, return false if path doesn't match
for (int i = 0, len = strlen(word); i < len; i++)
{
index = tolower(word[i]) - 'a';
if (index < 0)
{
index = 26;
}
if (trvl->children[index] == NULL)
{
return false;
}
else
{
trvl = trvl->children[index];
}
}
if (trvl->is_word == true)
{
return true;
}
else
{
return false;
}
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// TODO
// create a function to free nodes
// has to be a function so I can call it recursively
(freedom(root));
return true;
}
void freedom(node* trvl)
{
for (int i = 0; i< N; i++)
{
if (trvl->children[i] != NULL)
{
freedom(trvl->children[i]);
}
}
free(trvl);
}