0

Currently doing the pset5, and keep getting seg fault when running Valgrind. This is the error messsage I get:

/etc/profile.d/cli.sh: line 94:  1150 Segmentation fault      valgrind ./speller texts/cat.txt

Looks like your program is trying to access areas of memory that it isn't supposed to access. Did you try to change a character in a hardcoded string? Are you accessing an element of an array beyond the size of the array? Are you dereferencing a pointer that you haven't initialized? Are you dereferencing a pointer whose value is NULL? Are you dereferencing a pointer after you've freed it?

Thats what help50 highlights. I cant find whats causing the seg fault. Anny suggestions on what could it be? In theory, line 94 is on the load function, but after I change the code of load, the error is still in the same line, so Im not sure if thats even correct. Here is the code:

// Implements a dictionary's functionality
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>

#include "dictionary.h"

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

int word_count = 0;

// Number of buckets in hash table
const unsigned int N = sizeof(143000 * .75);

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    int key = hash(word);
    node *tmp = table[key];
    while(tmp->next != NULL)
    {
        if (strcmp(tmp->word, word) == 0)
        {
            return true;
        }
        else
        {
            tmp = tmp->next;
        }

    }
    // TODO
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    unsigned long hashed = 5381;
    int c;

    while ((c = *word++))
    {
        hashed = (((hashed << 5) + hashed) + c);
    }
    return hashed;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    node *n = NULL;
    char *dict_word = NULL;

    FILE *file = fopen(dictionary, "r");
    if (file == NULL)
    {
        return false;
    }
    while (scanf(dictionary, "%s", dict_word) != EOF)
    {
        dict_word = malloc(LENGTH);

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

        n = malloc(sizeof(node));
        if (n == NULL)
        {
            return false;
        }
        strcpy(n->word, dict_word);
        n->next = NULL;

        int key = hash(dict_word);
        n->next = table[key];
        table[key] = n;
        word_count++;
    }
    fclose(file);
    return true;
}

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

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

The other functions surely arent right, but I cant even test them with this seg fault error. Any help would be really appreciated. Thanks in advance for reading.

1 Answer 1

1

I see a couple problems. First, the dict_word pointer points at NULL when the while loop starts, so that's going to fail.

Second, should the while loop be using scanf or fscanf?

That should get you going. There may be more issues.

1
  • God, didnt even saw the fscanf error, thanks. The seg fault keeps happening after changing the dict_word pointer. Could it be that the pointers of n and table[key] are not pointing in the right direction? Commented Jul 1, 2020 at 15:18

You must log in to answer this question.

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