Question

I'm taking an online computer science MOOC from Harvard (CS 50) and for one of the problem sets, you have to load a dictionary into some sort of data structure (I chose a Trie) and then use said data structure to check info. I'm at the point where I'm writing my function which loads the dictionary and I've been presented some what of a major problem. My trie, despite attempts to detect NULL pointers, keeps allocating memory.

Here is my code:

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "dictionary.h"
#include <ctype.h>
//Defines the trie data structure which is used to store the words
struct trieNode{
    char letter;
    bool wordComp;
    bool isRoot;
    struct trieNode* childNodes[27];
 }trie;
 //The trie that will be used for the rest of the program
 struct trieNode root;
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{
    // TODO
    return false;
}

/**
 * Loads dictionary into memory.  Returns true if successful else false.
 */
bool load(const char* dictionary)
{
    //Counts to see whether the word was just an \n or it was really a word
    int cLettCount = 0;
    //counts the number of total words used
    int tWordCount = 0;
    //basic setup stuff
    root.isRoot = true;
    //Pointer to the current node (current node starts as root node).
    struct trieNode* currNode = &root;
    FILE* dic = fopen(dictionary, "r");
    char currChar = 1;
    //main loop (Goes till end of file)
    while(currChar != EOF){
        //resets letter count
        cLettCount = 0;
        //resets currNode to the root node
        currNode = &root;
        currChar = 1;
        //Loop gathers current word and pushes the letters to the trie
        for(int j = 0;  currChar != '\n'; j++){
            currChar = fgetc(dic);
            //Makes sure we're not at the end of a word or at EOF
            if(currChar == '\n'|| currChar == EOF)
            {
                break;
            }
            //Makes sure we only get alpha chars
            else if(!isalpha(currChar) && currChar != 39)
            {
                printf("Nonalpha char %c detected. Quiting...\n", currChar);
                return false;
            }
            //Meat and bones. Adds letters onto the trie
            else
            {
                bool isNull = false;
                if(currChar == 39){
                    currNode = currNode->childNodes[26];
                    if(currNode->childNodes[26] == NULL)
                    {
                        isNull = true;
                    }
                }
                else
                {
                //Finds the node that corrosponds with the letter
                    if(currNode->childNodes[currChar - 97] == NULL)
                    {
                        isNull = true;
                    }
                    currNode = currNode->childNodes[currChar - 97];
                }
                if(isNull)
                {
                     currNode = malloc (sizeof (trie));
                     currNode->isRoot = false;
                     currNode->letter = currChar;
                     currNode-> wordComp = false;
                     printf("Node created for: %c\n", currNode->letter);
                }else if(!isNull){
                    printf("Node not created\n");
                }
            }
        }
        if(currChar == EOF){
                break;
        }
        else if(currChar == '\n'){
            currNode -> wordComp = true;
            tWordCount++;
            printf("\n");
        }
    }
    return true;
}

/**
 * Returns number of words in dictionary if loaded else 0 if not yet loaded.
 */
unsigned int size(void)
{
    // TODO
    return 0;
}

/**
 * Unloads dictionary from memory.  Returns true if successful else false.
 */
bool unload(void)
{
    // TODO
    return false;
}

Load() is where my problem is.

Was it helpful?

Solution

You beat me to it, I need to learn to type faster :)

First, some nitpicking:

Don't use hard code numbers for character constants

 39 should be '\''
 97 should be 'a'

Note that uppercase letters will crash the program. Always range check after converting external input to array index, e.g.

index = currChar - 'a';
if ( index < 0 || index > 25 )
   return false;

Now for the meat:

The code creates a new node when it detects a NULL node. However, it does not store the pointer to the new Node in the parent Node. Therefore, the pointer in the parent Node will always be NULL.

OTHER TIPS

I think I just figured out my own mistake. I was setting curNode to the new node, but not the pointer in the root Node.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top