0

Can anyone help with segmentation fault. I have tried running debug50 and aparently the fault hits at line "if (head -> next != NULL)" in the load function. Aparently "table" is null despite already being declared.

// Implements a dictionary's functionality

#include <stdbool.h>
#include <cs50.h>
#include <stdlib.h>
#include <stdio.h>
#include "dictionary.h"
#include <string.h>
#include <ctype.h>

#define HASHTABLE_SIZE 10000


unsigned int hash(const char *hash_this);
// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;
int values = 0;
// Number of buckets in hash table
const unsigned int N = 10000;

// Hash table
node *table[N];

// Returns true if word is in dictionary, else false
bool check(const char *word)
{
    // TODO
    
    char low_word[LENGTH + 1];

    for (int i = 0; i < LENGTH; i++)
        {
            if (isalpha(word[i]))
            {
                low_word[i] = tolower(word[i]);
            }
        }
    int hash_index = hash(low_word);
    node *cursor = table[hash_index] -> next;
    if (cursor -> next != NULL)
    {
        while (cursor -> next != NULL)
        {
            if (cursor -> word == low_word)
            {
                return true;
            }
            else
            {
                cursor = cursor -> next;
            }
        }
        return false;

    }
    else
    {
        return false;
    }

}

// Hashes word to a number
unsigned int hash(const char *hash_this)
{
    unsigned int hash = 0;
    for (int i = 0, n = strlen(hash_this); i < n; i++)
    {
        hash = (hash << 2) ^ hash_this[i];
    }
    return hash % HASHTABLE_SIZE;
}


// Loads dictionary into memory, returnina true if successful, else false
bool load(const char *dictionary)
{
    // TODO
    FILE *dict = fopen(dictionary, "r");
    if (dict == NULL)
    {
        printf("Invalid Dictionary\n");
        return false;
    }
    values = 0;
    char word[LENGTH + 1];
    while (fscanf(dict, "%s", word) != EOF)
    {
        for (int i = 0; i < LENGTH; i++)
        {
            if (isalpha(word[i]))
            {
                word[i] = tolower(word[i]);
            }
        }
        
        node *newNode = malloc(sizeof(node));
        if (newNode == NULL)
        {
            return false;
        }
        strcpy(newNode -> word, word);
        newNode -> next = NULL;

        int hash_index = hash(newNode -> word);
        node *head = table[hash_index];
        if (head -> next != NULL)
        {
            newNode -> next = head -> next;
        }
        head -> next = newNode;
        values++;
    }
    return true;
}

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


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

Initially you have declared node *table[N] as global pointer. As you might have already guessed, all global variables/ pointers are set to default values.(In this case, each pointer is set to NULL).

So head = table[hash_index]; // It's still NULL

When you do head->next, you're trying to de-reference NULL which results in seg-fault.

5
  • This is inaccurate and fails to identify the real problem. First, pointers are never "set to default values" when created. Pointers will contain whatever garbage data that remains in the physical memory assigned to the location of the pointer. That content is completely unpredictable. It could be anything. Worst case, it could be a valid memory address for the program and could corrupt program data. Second, see my answer.
    – Cliff B
    Apr 11 at 17:40
  • @CliffB I've clearly mentioned that it's global variables/ pointers. And yes they are set to either zeros, '\0'(if they are variables), NULL(in-case of pointers) depending on data-type
    – C--
    Apr 11 at 17:43
  • @CliffB Perhaps good explanation here: Global variables default values. Please have good read-up
    – C--
    Apr 11 at 17:47
  • I've taken a closer look and done some testing. I stand corrected. I was wrong. While pointers within main or a function are not initialized, globals are set to null. I've deleted my incorrect comments. Having said that, it's always a best practice to manually initialize ANY var before their first use. Just goes to show that anyone can learn something new. ;-)
    – Cliff B
    Apr 12 at 1:06
  • @CliffB Perhaps it's time we stop judging contributors based on reputation ;)
    – C--
    Apr 12 at 9:52

You must log in to answer this question.

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