I would love a bit of help on cs50's pset5 speller. The program does compile. However, when I run valgrind ./speller texts/cat.txt
I get a segmentation fault . I think I am overlooking something but I can't figure out what. Could someone please help me identify where the error(s) lies?
// Implements a dictionary's functionality
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include "dictionary.h"
#include <string.h>
#include <ctype.h>
#include <strings.h>
int count = 0;
// 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 = 26;
// Hash table
node *table[N];
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
// TODO
char *term = NULL;
strcpy(term, word);
int array_location = hash(term);
for(node *find = table[array_location]; find != NULL; find = find->next)
{
if (strcasecmp(word, find->word) == 0)
{
return true;
}
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO
char first_letter = *word;
char capital_letter = toupper(first_letter);
int letter_number = atoi(&capital_letter);
int hash_code = letter_number - 65;
return hash_code;
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// TODO
for(int y = 0; y < 26; y++)
{
table[y] = NULL;
}
FILE *f = fopen("dictionary", "r");
if (f != NULL)
{
char *term = NULL;
while(fscanf(f, "%s", term) != EOF)
{
fscanf(f, "%s", term);
node *nd = malloc(sizeof(node));
if (nd != NULL)
{
strcpy(nd->word, term);
int array_location = hash(term);
if(table[array_location] == NULL)
{
nd->next = NULL;
table[array_location] = nd;
count++;
}
else
{
nd->next = table[array_location];
table[array_location] = nd;
count++;
}
}
else
{
fclose(f);
return false;
}
}
}
else if (f == NULL)
{
fclose(f);
return false;
}
fclose(f);
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// TODO
return count;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
// TODO
for(int i = 0; i < 26; i++)
{
node *marker = table[i];
node *deleter = marker;
while (deleter != NULL)
{
marker = marker->next;
free (deleter);
deleter = marker;
}
}
return false;
}
The following is what valgrind returns:
==413== Memcheck, a memory error detector
==413== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==413== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==413== Command: ./speller texts/cat.txt
==413==
==413== Invalid read of size 4
==413== at 0x4A28F5B: fclose@@GLIBC_2.2.5 (iofclose.c:48)
==413== by 0x401C0D: load (dictionary.c:97)
==413== by 0x4012CE: main (speller.c:40)
==413== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==413==
==413==
==413== Process terminating with default action of signal 11 (SIGSEGV)
==413== Access not within mapped region at address 0x0
==413== at 0x4A28F5B: fclose@@GLIBC_2.2.5 (iofclose.c:48)
==413== by 0x401C0D: load (dictionary.c:97)
==413== by 0x4012CE: main (speller.c:40)
==413== If you believe this happened as a result of a stack
==413== overflow in your program's main thread (unlikely but
==413== possible), you can try to increase the size of the
==413== main thread stack using the --main-stacksize= flag.
==413== The main thread stack size used in this run was 10485760.
==413==
==413== HEAP SUMMARY:
==413== in use at exit: 0 bytes in 0 blocks
==413== total heap usage: 1 allocs, 1 frees, 472 bytes allocated
==413==
==413== All heap blocks were freed -- no leaks are possible
==413==
==413== For lists of detected and suppressed errors, rerun with: -s
==413== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault