Home > front end >  Segmentation Fault in speller.c - CS50
Segmentation Fault in speller.c - CS50

Time:08-05

I am currently working on the pset5 of CS50, however I am stuck on the first function that needs to be done: load(). The load function should load all the string from a file "dictionary" and should return true if all the file has been loaded, and return false when the program should run into an issue while loading them (e.g. running out of space). I completed the function however when I try to run (after compiling) it gives me a segmentation fault, but I cannot understand where it comes from.

Here is my code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdbool.h>
    
    #include "dictionary.h"
    
    typedef struct node {
        char word[LENGTH   1];
        struct node *next; } node;
    
    const unsigned int N = 26;
    
    node *table[N];
    
    // Hashes word to a number
    unsigned int hash(const char *word)
    {
        int i = toupper(word[0]) - 'A';
        return i;
    }
    
    // Loads dictionary into memory, returning true if successful, else false
    bool load(const char *dictionary)
    {
        // Allocate temporary memory
        char *tmp = malloc(LENGTH   1);
        if (tmp == NULL)
        {
            printf("Could not open file\n");
            return false;
        }
    
        // Open file
        FILE *d = fopen(dictionary, "r");
        if (d == NULL)
        {
            printf("Could not open file\n");
            return false;
        }
    
        // Until EOF: create new node, point new node to table[key] -> next, point table[key] to new node.
        while (fscanf(d, "%s", tmp) != EOF)
        {
            node new;
            int key = hash(tmp);
    
            strcpy(new.word, tmp);
            new.next = table[key] -> next;
            table[key] -> next = &new;
        }
    
        free (tmp);
        return true;
    }

For more information you can refer here: https://cs50.harvard.edu/x/2022/psets/5/speller/

Can you help me understand where the seg fault issue is?

CodePudding user response:

In this while loop

    while (fscanf(d, "%s", tmp) != EOF)
    {
        node new;
        int key = hash(tmp);

        strcpy(new.word, tmp);
        new.next = table[key] -> next;
        table[key] -> next = &new;
    }

the local variable new is created anew in each iteration of the loop. The previously used variable new is not alive in each iteration of the loop.

And in any case the variable new will not be alive after executing the while loop.

You need to allocate an object of the type node dynamically as for example

node *new = malloc( sizeof( *new ) );

Another problem is that the array table contains initially null pointers. So this expression

table[key] -> next

invokes undefined behavior.

Instead you should write (new is a pointer as I already showed)

new->next = table[key];

That is a new node is inserted in the beginning of the list.

CodePudding user response:

I see two problems in your code, first, when you call malloc function, I think it should be char *tmp = malloc((LENGTH 1)*sizeof(char)); the second thing I want to tell you is that you make an fopen, but you don't make an fclose at the end of your program.

I don't know if this is going to solve your problem, but if it continues check if you are accessing to a position of the array table that does not exist.

  • Related