0

When in my load function, I insert a node at the front of a linked list:

If I declare and initialize a pointer as the new 'head' node, my code compile but every word in the text is found to be misspelt (i.e. the dictionary is silently not loading correctly) - see else branch below.

If I instead use hashtable[hash(word)] directly and without trying to initialize a pointer, which to me is at face value the same but not DRY, everything works perfectly.

It took me hours to find this and I cannot understand why the two behave differently. Can you help me to understand what is happening here so that I do not simply progress without 'getting' what is happening under the bonnet?

bool load(const char *dictionary)

{

// [UNNECESSARY CODE OMITTED AND SIGNPOSTED AS COMMENTS]
// Open dictionary to read from

// Pointer to a buffer for a word

// Loop through the dictionary, loading words into 'word' using the new node at front approach
while (fscanf(file, "%s", word) != EOF)
{

    // Allocate memory for each linked list node
    node *new_node = calloc(1, sizeof(node));

    // Error check as the node will not be created if the program runs out of memory

    else
    {
        // 2. If the node succeeds, copy the 'word' into your node (syntax: dest, source)
        strcpy(new_node->word, word);

        // ---> PROBLEM: New_node should point to whatever was previous in list
        node *head = hashtable[hash(word)];
        new_node->next = head;
        head = new_node;

        // count the new word added
        wordsLoaded++;
    }

}

// Close dictionary


// Indicate success

}

1 Answer 1

0

head is a local variable. With head = hashtable[hash(word)], you copy the pointer, but there is no further connection between the variables other than now both having same value. If you later change the pointer head, this is not reflected in hashtable[hash(word)]. Like

int num = 23;           // an integer used as the pointee
int num_ptr = #     // the pointer
int num_ptr2 = num_ptr; // a copy of the pointer

// changing the pointee changes it for both pointers
*num_ptr = 42;
printf("%i\n", *num_ptr2); // 42

// changing one of the pointers does not change anything for the other one
num_ptr = NULL;
printf("%i\n", *num_ptr2); // still 42

I'd assign hash(word) to another variable, so that you call the function once, not twice.

edit: So this would work

int index = hash(word);
new_node->next = hashtable[index];
hashtable[index] = new_node;

or this

node **head_ptr = &hashtable[hash(word)];
new_node->next = *head_ptr;
*head_ptr = new_node;                     // changes the head pointer itself

with head_ptr being a pointer to the list head (which itself is a pointer to the first node).

3
  • So far as I understand correctly, this isn' a working solution for me: The implication of what you are saying if I understand correctly is to add an asterisk to the end line, making: int variable = hash(word); node *head = hashtable[variable]; new_node->next = head; *head = new_node; however, this causes compiler errors. I do see why int variable = hash(word) followed by node *head = hashtable[variable] saves on the double function call - tks Commented Sep 26, 2019 at 20:58
  • I added two examples how one could handle this. One reuses hashtable[index], the other declares a pointer to the list head pointer.
    – Blauelf
    Commented Sep 27, 2019 at 8:11
  • Thanks, your second suggestion showed where the problem with the code that didn't work as shown in my original post - not enough asterisks (your first suggestion "so this would work" is what I had used to originally pass the pset). int variable = hash(word); node **head = &hashtable[variable]; new_node->next = *head; *head = new_node; Commented Oct 14, 2019 at 20:17

You must log in to answer this question.

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