0

When I run my load function there is a segmentation fault. It comes at line 80 in my code node* n = malloc(sizeof(node));. I am unsure of how to fix this error. Moreover, I changed my code many times and previously have had Null Hash Tables. Sorry about the poorly designed code, however it is hard to format in Stack Exchange.

// Implements a dictionary's functionality

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

#include "dictionary.h"

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

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

// Hash table
int i, counter;
node* table[N];


//Returns true if word is in dictionary else false
bool check(const char *word)
{
//attempts to navigate through the hash table to find the word
int hashkey = hash(word);
node* temp = table[hashkey];
while(temp != NULL)
{
    if (strcasecmp(temp->word, word)== true)
    {
        return true;
    }
  temp = temp ->next;
}
return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
{
//a hash function ive seen on the internet
   unsigned long hash = 5381;
int c = *word;
c = tolower(c);
while (*word != 0)
{
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
c = *word++;
c = tolower(c);
}
return hash % N;
}
}

bool load(const char *dictionary)
{
FILE* a = fopen(dictionary, "r");
//opens dictionary
if (a==NULL)
{
    return false;
}
//declares variables
unsigned int key;
i = 0;
 char buffer[counter + 1];
//reads the file
while(fscanf(a, "%s", &buffer[i])!= EOF)
{
 key = hash(&buffer[i]);
 //creates the node
node* n = malloc(sizeof(node));
if (n == NULL)
{
    return false;
}
//assigns the nodes value
strcpy(n->word, &buffer[i]);
//checks to see if the tables head pointer is null, and creates head pointer
    if (table[key] == NULL)
    {
        n->next = NULL;
        table[key] = malloc(sizeof(node)+ 1);
        table[key] = n;

    }
    else
    {
        //we assign the next value of the head node to n, and then change the head node to the current node we are modifying
        n->next = table[key];
        table[key] = n->next;
    }
i++;
}
fclose(a);
return true;
}


// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
int counter_1 =0;
 //reads through the node table to see how many words are in the dictionary
 for (int iteration = 0; iteration < N;iteration++ )
{
node* cursor = table[i];
while(cursor!= NULL)
{
counter_1++;
counter++;
cursor = cursor->next;
}
}
return counter_1;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
node* cursor, *temp, *cursor1, *temp2;
for (int a = 0; a < N; a++)
{
    cursor = table[a];
    temp = cursor->next;
    if (cursor == NULL)
    {
        return false;
    }
    while(cursor != NULL)
    {
        //frees what cursor is pointing to and then assigns the next node for both cursor and temp
        free(cursor);
        cursor = temp;
        temp = temp->next;

    }
 }
return true;    
 } }
1
  • Sorry I used Valgrind and there are multiple errors from Valgrind. I am not sure of what my error is, however. – Ansar Sherkhanov May 27 at 5:56
0

First, there are some minor compile errors - unused vars and an extraneous closing curly brace. Once removed, the program compiles fine.

Second, the seg fault is not in load. This is evident since the program starts checking that words are spelled correctly.

The seg fault is actually occurring in the unload function. Hint: given a var pointer node *x, when x is NULL, does x->next exist?

It looks like you've assumed that the problem is with line 80 in the code because that's something that valgrind said. That's not exactly true. Valgrind was reporting that the issues with memory are related to memory that's actually allocated at line 80. It's only telling you where the memory was allocated, not where the problem actually lies. It does this to give you a clue about what memory is affected.

The code is still flawed. It reports that all words are misspelled, even when using a small dictionary file as the text file to be tested. (Should produce no misspelled words.) This means that there are serious errors in the code somewhere, but that's for another question. This is about the seg fault.

Programmers should be careful about using valgrind. While it can be useful to give clues, it's more important to debug the program to get it right. THEN, use valgrind to find additional problems and memory leaks. Often, bugs in a program cause memory errors reported by valgrind. Focus on making the program run correctly,or why it doesn't, rather than what valgrind "says".

You should also spend some quality time with style50 and learn better indenting skills for writing code.

Finally, learning how to identify exactly where a seg fault lies is a critical debugging skill. You would benefit from reading this:

Do YOU know how to find a seg fault?? Advice to new programmers

If you have more questions, post a comment.

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

2
  • Thanks for this information. By any chance is it possible for you to tell me how my program printed out the misspelled words, as when I debug the program, the error happens to be in my load function. – Ansar Sherkhanov May 28 at 19:28
  • All I did was compile and run the program to test it. Have you saved the latest code and are you compiling the right source code file? Here's a tip. Put a printf at the end of the load function (before the return statement) to see if it executes outside of debug. – Cliff B May 28 at 22:15

You must log in to answer this question.

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