0

I use a simple (or so I thought) code to load the dictionary, no optimization. Yet I keep getting into segmentation fault. In this example I use the small dictionary, which only has 2 words. In my code, I would have expected my while() loop to run 2 times. Using gdb, however, I seem to have found that the while() loop always run 3 times instead. Thus, the 3rd time it runs, it seems to load up N->word with Null value, then messes up the value variable to a negative value (value becomes (0 - 97)%26, which then messes up the next 2 pointer assignment sentences. That's my understanding, but I'm not sure how to fix it. Help appreciated.

bool load(const char* dictionary)
{
    // Initializes a hash table made up of pointers to singly linked lists
    for (int i = 0; i < n; i++)
    {
        table[i] = malloc(sizeof(node));
        table[i] -> next = NULL;
    }
    //set up to load dictionary
    FILE *ptr = fopen(dictionary,"r");

    //The hash function simply modulus the first letter and put the words   into linked lists corresponding to 26 buckets
    while (fgetc(ptr) != EOF)
    {
        node *N = malloc(sizeof(node));
        fscanf(ptr,"%s",N->word);
        int value = (N->word[0] - 97) % n;
        //insert the new node into the beginning of the linked list ie. linked list kinda sorted backwards!
        N->next = table[value]->next;
        table[value]->next = N;
    }

    return true;
}

1 Answer 1

2

There is one mistake here:

while (fgetc(ptr) != EOF)

doesn't just work as a condition, but it does read a char and moves on, so next time you read a string it's gonna miss the first char of the word because it was read by fgetc(). Fix that and report back. I would suggest you use the fscanf() in your loop condition instead (but then remove it from inside the body of the loop).

Also, you would be better of declaring table as node* table[n], so that the members of table are just pointers to nodes, not nodes themselves. In fact, you never use the nodes created in your table. You just use their next attribute, which is itself a pointer to node.

Maybe you are trying to read the word stored in table[i] somewhere in your code, but since there is nothing there you get the segfault.

2
  • Thanks ChrisG, but that doesn't answer my question: - regarding fgetc(ptr) != EOF, yes I did realized it was missing the first character (so that I only got 'at' instead of 'cat', but that did not cause the segmentation fault. I tried it just because I wanted to be really sure the while() loop does not run 1 time too many (but I still didn't succeed). - On the table declaration, I did not show the code but it was indeed declared globally as node *table[n]. So my global declaration plus the for() loop to malloc() the table do exactly the same thing as you were saying.
    – buitri84
    Commented Sep 22, 2015 at 10:21
  • Then that's why you get the segfault. If you declared table as node* table[n], table is just a pointer for nodes. So since it's not a node itself, it doesn't have the next attribute itself. So when try to load your first node, table[value] points to NULL, and since you try N->next = table[value]->next; the segfault occurs. You try to access NULL->next
    – ChrisG
    Commented Sep 22, 2015 at 11:09

You must log in to answer this question.

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