0

I've been getting a seg fault in load on this line: strcpy(new_node->string,word); I try to use gdb to print "word",it shows "\177ELF\002\001\001\000\000\000\000\000\000\000\000\000\002\000>\000\001\000\000\000\260\a@\000\000\000\000\000@\000\000\000\000\000\000\000@>\000\000\000" Any help would be much appreciated. I've been stuck for hours and I am quite clueless how to proceed.

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

#include "dictionary.h"



//define the struct of the children node
typedef struct node  
{
    char string[LENGTH+1];
    struct node* next;
}
node;

    //create an array of buckets
    node* hashtable[26] ;
    //define hash function
    int hash_function(char c)
    {
        //hash on first letter of string
        int hash_code = tolower(c) % 'a';
        return hash_code;
    }



    //size of hashtable
    unsigned int total_nodes = 0;
    /**
     * Returns true if word is in dictionary else false.
     */
    bool check(const char* word)
    {
        int len = strlen(word);
        char new_word[len];
        for(int i = 0; i < len; i ++)
        {
            if (isalpha(word[i]))
            {
                new_word[i] = tolower(word[i]);
            }
            if(word[i] == '\'')
            {
                new_word[i] = word[i];
            }
        }
        int hashcode = hash_function(new_word[0]);
        node* cursor = malloc(sizeof(node));
        cursor = hashtable[hashcode];
        // got to corresponding bucket
        if (cursor->next == NULL) 
        {
            // if NULL word is mispelled
            return false;
        }
        // if not NULL, search for the word in the whole list
        while(cursor->next!=NULL)
        {
            if(cursor->string == word)
            {
                return true;
            }
            else
            {
                cursor = cursor->next;
            }
        }
        free(cursor);
        return false;
    }

    /**
     * Loads dictionary into memory.  Returns true if successful else false.
     */
    bool load(const char* dictionary)
    {
         // Read dictionary
        FILE* fp = fopen(dictionary, "r");
        if (fp == NULL)
        {
            printf("Could not open %s.\n", dictionary);
            unload();
            return false;
        }

        // Read each string in dictionary
        char word[LENGTH+1];
        while (fscanf(fp,"%s",word) != EOF)
        {
            printf("%s\n",word);
            node* new_node = malloc(sizeof(node));
            if(new_node == NULL)
            {
                unload();
                return false;
            }
            new_node->next = NULL;
            strcpy(new_node->string,word);

            int hashcode = hash_function(word[0]);
            printf("%i\n",hashcode);
            if(hashtable[hashcode]->next==NULL)
            {
                hashtable[hashcode]->next = new_node;
            }
            else{
                new_node->next = hashtable[hashcode]->next;
                hashtable[hashcode]->next = new_node;
            }
            total_nodes ++;
        }

        // Close dictionary
        fclose(fp);
        return true;
    }

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

     /* Check node's followers to see if they can be freed
     */
    void free_nodes(node* trav)
    {
        if (trav->next != NULL) 
        {
            free_nodes(trav->next);
        }
        free(trav);
        printf("%s\n",trav->string);
    }


    /**
     * Unloads dictionary from memory.  Returns true if successful else false.
     */
    bool unload(void)
    {
        for(int i =0; i < 26; i++)
        {
            node* head = hashtable[i]->next;
            free_nodes(head);
        }
        return false;
    }
2

In your definition,

typedef struct node  
{
    char* string;
    struct node* next;
}
node;

string is a pointer, but space hasn't been allocated. When the code executes the strcpy, there's no memory allocated for the target, so it seg faults. Try changing the typedef to match word's declaration so that the space will automatically be allocated when a node is created:

typedef struct node  
{
    char string[LENGTH+1];
    struct node* next;
}

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

2
  • I tried to change the typedef,but there is also segmentation fault in load function. If I ignore the code if(hashtable[hashcode]->next==NULL) {....}else{....}, the unload function will work well. I am wondering what is wrong with the code for inserting words in a list. – Charlotte Nov 24 '16 at 17:19
  • This is a new problem. This code, ` if(hashtable[hashcode]->next==NULL) ` is the issue. It tries to test a child element, but the root, hashtable[hashcode] is NULL, so the child doesn't exist, thus generating a seg fault. They're null because there is no code to insert the first element of each linked list in the appropriate array element. If you fix this and have a new problem, please post a new question. – Cliff B Nov 24 '16 at 19:20

You must log in to answer this question.

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