So I've been testing speller and checked it with the staff solution and get matching outputs (click here for comparison).
But when I run with valgrind every word is mispelled.
valgrind --leak-check=full ./speller texts/ralph.txt
==7550== Memcheck, a memory error detector
==7550== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7550== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7550== Command: ./speller texts/ralph.txt
==7550==
MISSPELLED WORDS
When
I
grow
up
I
want
to
be
a
principal
or
a
caterpillar
I
love
you
Principal
Skinner
Ralph
Wiggum
WORDS MISSPELLED: 20
WORDS IN DICTIONARY: 1439228
WORDS IN TEXT: 20
TIME IN load: 3.86
TIME IN check: 0.00
TIME IN size: 0.00
TIME IN unload: 0.00
TIME IN TOTAL: 3.86
==7550==
==7550== HEAP SUMMARY:
==7550== in use at exit: 0 bytes in 0 blocks
==7550== total heap usage: 3 allocs, 3 frees, 1,368 bytes allocated
==7550==
==7550== All heap blocks were freed -- no leaks are possible
==7550==
==7550== For counts of detected and suppressed errors, rerun with: -v
==7550== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Clearly, something is going wrong with valgrind. My dictionary size is huge ,but only 3 allocs are detected? So obviously, I can't pass any of the checks either since every word is detected as misspelled.
Can anyone help me figure out why I'm getting this problem?
Here's my full code.
/**
* Implements a dictionary's functionality.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include "dictionary.h"
// Declare dictionary struct
typedef struct node {
bool is_word;
struct node *children[27];
int size;
}
node;
struct node *root = NULL;
struct node *current = NULL;
bool recursionCheck(int i, const char* word);
bool recursionUnload(node* pointer);
int NODESIZE = sizeof(struct node);
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char *word)
{
//cat test
// if (root->children['c'-97]!=NULL &&
// root->children['c'-97]->children['a'-97]!=NULL &&
// root->children['c'-97]->children['a'-97]->children['t'-97]!=NULL){
// printf("cat is in the dictionary\n");
// printf("%d \n", root->children['c'-97]->children['a'-97]->children['t'-97]->is_word);
// return true;
// }
// initialize variables
// printf("incoming word is %s\n", word);
// printf("the first letter is %c\n", word[0]);
return recursionCheck(0, word);
}
/**
* Recursion search function helper
*/
bool recursionCheck (int i, const char *word){
char c;
//printf("%s is %lu letters\n", word, strlen(word));
//printf("The dictionary size is %i\n", root->size);
// convert letter to lowercase
if(word[i]>='A' && word[i]<='Z'){
c = word[i] + 32;
} else {
c = word[i];
}
// convert locwercase letter to 0-26
int loc;
if (c == '\''){
loc = 26;
} else {
loc = c - 97;
//printf("%c = %i \n", c, loc );
}
// check if child is null aka check if letter exists in dictionary
if (current->children[loc] == NULL) {
current = root;
return false;
} else {
// check if end of the word
if (i==strlen(word)-1) {
//printf("checking end of word... \n");
// reset variables
node *test = current->children[loc];
current = root;
//printf("%d \n", test->is_word);
return test->is_word;
} else {
current = current->children[loc];
i++;
return recursionCheck(i, word);
}
}
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char *dictionary)
{
// Open File
FILE *fp = fopen(dictionary, "r");
// check if dictionary can be opened
if (fp == NULL){
fprintf(stderr, "Dictionary %s cannot be opened. \n", dictionary);
return false;
}
// declare important variables
root = calloc(1,NODESIZE);
root->size =0;
current = root;
int reading = 1;
char C[1];
while(reading == 1){
// check if end of file
if(feof(fp)){
reading = 0;
// close files
fclose(fp);
// readjust dictionary size;
root->size--;
//printf("The dictionary size is %i", root->size);
current = root;
return true;
}
// read next character
fread(C, 1, 1, fp);
// check if end of word
int end = strcmp(C, "\n");
if (end == 1){
// set is_word to true
current->is_word = true;
if (current->is_word == true){
root->size++;
}
// reset current
current = root;
} else {
int loc;
//printf("%s", C);
if (*C == '\''){
loc = 26;
} else {
loc = *C - 97;
}
// create node if child is NULL
if (current->children[loc] == NULL) {
current->children[loc] = calloc(1,NODESIZE);
}
// update current
current = current->children[loc];
}
}
fclose(fp);
return false;
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
return root->size;
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
return recursionUnload(root);
}
bool recursionUnload(node * pointer){
// TODO
for (int i = 0; i <27; i++){
if (pointer->children[i] != NULL){
node *temp = pointer->children[i];
recursionUnload(temp);
}
}
free(pointer);
return true;
}