0

I've been having great difficulty with implementing the load() function.

bool load(const char* dictionary)
{
    // Define node structure
    typedef struct node
    {
        bool is_word;
        struct node* children[27];
    }
    node;

    // Open dictionary
    FILE* dict = fopen(dictionary, "r");
    if (dictionary == NULL)
    {
        printf("Could not open dictionary.\n");
        return -100;
    }

    // Create root and set all pointers to NULL
    node* root = malloc(sizeof(node));
    root->is_word = false;
    for (int i = 0; i < 28; i++)
    {
        root->children[i] = NULL;
    }

    // Creat a traversal node
    node* trav = malloc(sizeof(node));
    trav = root;

    // Create a buffer that holds words from dictionary
    char word[46];

    while (fscanf(dict, "%s", word) != EOF)
    {
        for (int i = 0, l = strlen(word); i < l; i++)
        {
            int index = word[i] - 'a';
            if (i == 0)
            {
                if (root->children[index] == NULL)
                {
                    node* new_node = malloc(sizeof(node));
                    trav->children[index] = new_node;
                }
                else
                {
                    trav = trav->children[index];
                }
            }
            else
            {
                trav = trav->children[index];
            }
            if (trav->children[index] == NULL)
            {
                    node* new_node = malloc(sizeof(node));
                    trav->children[index] = new_node;
            }    
            else
            {
                trav = trav->children[index];
            }
        }

        trav->is_word = true;
        trav = root;
    }

    fclose(dict);

    return true;
}

The first problem I encounter is the root node not being set to NULL; valgrind says that, when I try to NULL all children in root, "address is 0 bytes after a block of size 224 alloc'd". How can the program be looking for an address after the malloc'd block?

Secondly, I'm very shaky on the concept of recursive pointers. I've watched the lectures, walkthrough, and shorts, and I'm still fairly uncertain how to properly direct the pointers. Any tips on where to look for clearer direction would be greatly appreciated!

0

I see a couple of issues. The first is your for loop to initialize root:

for (int i = 0; i < 28; i++)

There are 27 children in the structure, numbered 0 to 26. Your loop is trying to initialize 28, numbered from 0 to 27. One too many.

Next, you have a memory leak here:

// Creat a traversal node
node* trav = malloc(sizeof(node));
trav = root;

This allocates memory with the creation and initialization of trav, but in the next line, immediately abandons the memory that was just allocated ( a very common mistake by new programmers.) Instead of malloc, do this:

node* trav=NULL;

It creates the pointer and sets it to null so no memory is allocated and/or lost. Or you could immediately assign it to root.

As for where to look for more info on recursive pointers, not sure where to point you. ;-)

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

5
  • What is the difference between creating trav with malloc and then "abandoning" the memory by assigning it root vs node* trav = root? How does the second scenario create trav without assigning it a block of memory? – Jake Feb 3 '16 at 19:05
  • You were actually doing several distinct activities. First, you create the pointer trav, an action independent of the assignment. Next you were allocating memory with malloc and pointing trav at that memory. In the next step, you were reassigning the pointer to root, another error in memory, but when you did that, you were 'forgetting' the previously malloc'd memory without freeing it, so it remains allocated to the program with no pointer to reference it. (continued...) – Cliff B Feb 3 '16 at 19:11
  • If you node* trav = root, you combine steps and eliminate the extraneous memory allocation. It creates the pointer trav, and then immediately points it at the memory that was previously allocated when the root pointer was created. Both the trav and root pointers will point at the same physical memory. Remember too that you can create a pointer, as in node* trav; without assigning anything to it, even though that's a bad programming practice. – Cliff B Feb 3 '16 at 19:15
  • Ahh, I get it. Thanks so much! – Jake Feb 3 '16 at 19:18
  • ooh, I hate spell checkers. Previous comment should have been "another area in memory," and not "another error in memory," – Cliff B Feb 3 '16 at 19:51

You must log in to answer this question.

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