0

I've tried to fiddle around with my unload function for a while and don't understand why I'm getting a seg fault. It seems that the unload function is running through completely at least once, but then creates a seg fault when it's called again? (All of the misspelled words are printed and are correct, immediately after the last misspelled word is printed is where the seg fault occurs)

Very confused, any suggestions would be appreciated. Thanks.

// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

unsigned int counter = 0;
bool loaded = false;

// Number of buckets in hash table
const unsigned int N = 26;

// Hash table
node *table[N]; //not using malloc to assign space, could use malloc?

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    char *wordlower = malloc(LENGTH);

    for (int i = 0; i < LENGTH; i++)
    {
        wordlower[i] = tolower(word[i]);
    }

    int index = hash(word);

    node *tmp = table[index];

    while (strcasecmp(wordlower, tmp->word) != 0)
    {
        if (tmp->next == NULL)
        {
            return false;
        }

        tmp = tmp->next;
    }
    if (strcasecmp(wordlower, tmp->word) == 0)
    {
        return true;
    }
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    return (tolower(word[0]) - 97) % 25;

}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }
    FILE *file = fopen(dictionary, "r");
    if (file == NULL)
    {
        return false;
    }

    char buffer[LENGTH + 1];

    while (fscanf(file, "%s", buffer) != EOF)
    {
        node *n = malloc(sizeof(node));

        if (n == NULL)
        {
            return false;
        }

        strcpy(n->word, buffer);

        n->next = NULL;

        int index = hash(n->word);



        n->next = table[index];
        table[index] = n;

        counter++;
    }
    loaded = true;
    fclose(file);
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    if (loaded == true)
    {
        return counter;
    }
    else
    {
        return 0;
    }
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    node *cursor = malloc(sizeof(node));
    for (int j = 0; j <= 25; j++)
    {
        cursor = table[j];
        if (cursor->next != NULL)
        {
            while (cursor->next != NULL)
            {
                node *tmp = malloc(sizeof(node));
                tmp = cursor;
                cursor = cursor->next;
                free(tmp);
            }
        }
    }
    free(cursor);
    return true;
}
1

Here's the issue:

    if (cursor->next != NULL)
    {
        while (cursor->next != NULL)

The problem is that if cursor is ever null, cursor->next doesn't exist. That will cause a seg fault. The code should be using cursor, not cursor->next. It's actually failing at the end of the for loop because table[25] is null. Keep in mind that when cursor->next is null, it will set cursor to null on the next pass, so it will work ok.

side note - there's a massive memory leak because pointers are being declared, and then initialized with malloc instead of NULL, and then the malloc'd memory is being discarded. I'll let you figure it out. There are other memory leaks too. Fix the bugs so that it runs first. THEN go after the memory leaks.

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

1
  • So simple! My program now runs. Now to go after all the fiddly bits! Thank you for your help! – ShippingTycoon Mar 19 '20 at 0:49

You must log in to answer this question.

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