0

This question is related with this other question of mine, in which I am trying to complete pset5: speller. I took Cliff's advice, and additionally executed the debug50 on my code. Since the original question, I did not make big changes in my code, but I bring a different question.

When I am running the debug50 I can see (screenshot below) that table, N and numofwords variables do not exist, when I click to execute the highlighted line of code, Process received SIGSEGV: Segmentation fault this error pops up in the top of the screen. Therefore, I understand that the problem is that I am trying to assign newNode->next = table[currHash]->next; but the computer is not "seeing" table as being anything (otherwise, it should be visible in the right panel, right?).

I still do not understand why the hash function did return something, if N is not visible, this does not fit entirely with what I said previously about table.

Finally, the "Hello world" did print and the first word (aka "a") was correctly assigned to strcpy(newNode->word, word);.

Am I interpreting correctly the right panel? And if so, how is my code wrong? I thought those 3 would be global variables.

Here's my current code and the screenshot of debug50. Thanks in advance for any ideas. debug50 screenshot before error

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

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

// Prototypes
bool traverse(node *head, const char *lookup);
void freelist(node *list);

// Number of buckets in hash table
const unsigned int N = 93;
unsigned int numofwords = 0;

// Hash table
node *table[N];

bool traverse(node *head, const char *lookup)
{
    if (strcasecmp(head->word, lookup) == 0)
    {
        return true;
    }
    else if(head->next == NULL)
    {
        return false;
    }
    else
    {
      return  traverse(head->next, lookup);
    }
}

// Returns true if word is in dictionary, else false
bool check(const char *word)
{
    // Handle case difference
    char *tmp = malloc(8 * strlen(word)) + 1;
    strcpy(tmp,word);
    *tmp = tolower(*tmp);
    unsigned int checkHash = hash(tmp);
    node *checkNode = table[checkHash];
    return traverse(checkNode, word);
    free(tmp);

}

// Hash function (djb2 by Dan Bernstein)
unsigned int hash(const char* str)
{
    unsigned int hash = 5381;
    int c;

    while ((c = *str++))
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
    return hash % N;
}

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

    char *word = malloc(LENGTH + 1);
    if(word == NULL)
    {
        return false;
    }
    node *newNode = malloc(sizeof(node));
    if(newNode == NULL)
    {
        return false;
    }
    unsigned int currHash;
    while(fscanf(dic,"%s",word) != EOF)
    {
        printf("Hello world\n");
        numofwords++;
        printf("%i",numofwords);
        // Initialize newNode attributes
        strcpy(newNode->word, word);
        printf("%s",newNode->word);
        newNode->next = NULL;
        //Hash new word
        currHash = hash(newNode->word);
        newNode->next = table[currHash]->next;
        table[currHash]->next = newNode;
    }
    free(word);
    free(newNode);
    fclose(dic);
    return true;
}

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

// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
    for (int i = 0; i < N; i++)
    {
        freelist(table[i]);
    }
    return true;
}

void freelist(node *list)
{
    if (list->next == NULL)
    {
        return;
    }
    freelist(list->next);
    free(list);
}

1 Answer 1

1

Look very carefully at all of the areas on the right side of the screen. Did you notice that the area that shows the vars and their content is called local variables?

It isn't that the vars you mentioned don't exist, they're just not displayed. They are all global vars, not local. If you want to see them, you can type in their names in the area titled "Watch Expressions". You can see vars, whole arrays, or even a particular array element like myarray[i] and they will be displayed as you go.

Given that it appears you didn't know this, I'll let you try again to debug. Also, spend some quality time looking at all the areas on the screen. Explore! Try entering stuff to see what happens. Experiment! You won't break anything. ;-)

You must log in to answer this question.

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