0

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);
}

1 Answer 1

0

For this problem, the dictionary is guaranteed to not have any words longer than LENGTH (which is defined in dictionary.h:

// Maximum length for a word
// (e.g., pneumonoultramicroscopicsilicovolcanoconiosis)
#define LENGTH 45

So if you send it a word longer than that, your program will have an error that you've seen.

5
  • Thank you for your quick response.
    – Sherri
    Jun 26, 2019 at 0:32
  • Thank you for your quick response. The error is happening in load(dictionary) which should not have access to words in *.txt I thought this code from speller.c would handle words read in from *.txt ``` for (int c = fgetc(file); c != EOF; c = fgetc(file)) { if (isalpha(c) || (c == '\'' && index > 0)) { ... // Ignore alphabetical strings too long to be words if (index > LENGTH) { while ((c = fgetc(file)) != EOF && isalpha(c)); index = 0; }```
    – Sherri
    Jun 26, 2019 at 0:56
  • What dictionary are you giving it when you run? As you say, speller handles the words that are sent to check, but you've said the issue is in load, which reads the words from the dictionary.
    – curiouskiwi
    Jun 26, 2019 at 2:24
  • AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHT is not in either the large or the small dictionary that was given in the distribution code. Are you sure you aren't passing the text as the dictionary? you should be running ./speller <dictionary> <text> maybe you've mixed them up?
    – curiouskiwi
    Jun 26, 2019 at 2:26
  • It does seem that <text> is being run through the <load> program. I do not recall telling it to do that. (Are we absolutely sure computers only do what we tell them to? ;) ).
    – Sherri
    Jun 27, 2019 at 21:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .