0

I hope you're doing well and I also hope you might help me. When I run my CHECK50 in my speller program. Everything is correct all green, but when I run my program or valgrind I have some errors. And I don't know why it's happening. Can you help me on these ones, please? It'd appreciated.

My check50:

https://submit.cs50.io/check50/c852723fefd803291052edf373b0a1320d11c068

My Output:

a                                                             <
Sebastian's                                                     Sebastian's
combo's                                                         combo's
Mia                                                             Mia
Sebastian's                                                     Sebastian's
Mia                                                             Mia
Mia                                                             Mia
Mia                                                             Mia
a                                                             <
MIA                                                             MIA
Mia                                                             Mia
A                                                             <
a                                                             <
Mia                                                             Mia
a                                                             <
Mia                                                             Mia
Sebastian's                                                     Sebastian's
L                                                               L
A                                                             <

WORDS MISSPELLED:     1470                                    | WORDS MISSPELLED:     955
WORDS IN DICTIONARY:  143091                                    WORDS IN DICTIONARY:  143091
WORDS IN TEXT:        17756                                     WORDS IN TEXT:        17756
TIME IN load:         0.02                                    | TIME IN load:         0.04
TIME IN check:        0.03                                    | TIME IN check:        0.02
TIME IN size:         0.00                                      TIME IN size:         0.00
TIME IN unload:       0.00                                    | TIME IN unload:       0.03
TIME IN TOTAL:        0.05                                    | TIME IN TOTAL:        0.09

My valgrind:

==23694== Memcheck, a memory error detector
==23694== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==23694== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==23694== Command: ./speller texts/pneumonoultramicroscopicsilicovolcanoconiosis.txt
==23694== 
==23694== Conditional jump or move depends on uninitialised value(s)
==23694==    at 0x109A13: hash (dictionary.c:78)
==23694==    by 0x109B53: load (dictionary.c:131)
==23694==    by 0x1092CB: main (speller.c:40)
==23694==  Uninitialised value was created by a heap allocation
==23694==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==23694==    by 0x109B14: load (dictionary.c:121)
==23694==    by 0x1092CB: main (speller.c:40)
==23694== 
...
==23694== 
==23694== HEAP SUMMARY:
==23694==     in use at exit: 0 bytes in 0 blocks
==23694==   total heap usage: 143,096 allocs, 143,096 frees, 8,023,256 bytes allocated
==23694== 
==23694== All heap blocks were freed -- no leaks are possible
==23694== 
==23694== For lists of detected and suppressed errors, rerun with: -s
==23694== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 0 from 0)

My code:

// Implements a dictionary's functionality

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

#include "dictionary.h"

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

// TODO: Choose number of buckets in hash table
const unsigned int N = 17576;

// Hash table
node *table[N];

//Dictionary Word
char dicword[LENGTH + 1];

//Variable that keeps track of the number of words in the dictionary
int number_words = 0;

// Returns true if word is in dictionary, else false
bool check(const char *word)
{
    // TODO
    unsigned int index_valuetocheck;
    // Using the hash function in the input word
    index_valuetocheck = hash(word);
    // Access to the correct index into the hash table
    node *ptr = table[index_valuetocheck];
    //Checking if the word is in the hash table
    while (ptr != NULL)
    {
        // Comparing the input word with the word in the dictionary
        if (strcasecmp(word, ptr->word) == 0)
        {
            return true;
        }
        //Otherwise go to the next node of the linked list
        ptr = ptr->next;
    }
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    // TODO: Improve this hash function
    char word1 = word[0];
    char word2 = word[1];
    char word3 = word[2];
    int char1 = 0;
    int char2 = 0;
    int char3 = 0;
    int char1_index = 0;
    int char2_index = 0;
    int char3_index = 0;
    if (word1 != '\0')
    {
        char1 = toupper(word[0]);
    }
    if (word2 != '\0')
    {
        char2 = toupper(word[1]);
    }
    if (word3 != '\0')
    {
        char3 = toupper(word[2]);
    }

    if (char3 >= 65)
    {
        char3_index = char3 - 'A';
    }
    if (char2 >= 65)
    {
        char2_index = char2 - 'A';
    }
    int char2_char3_t = char2_index * 26 + char3_index;
    if (char1 >= 65)
    {
        char1_index = char1 - 'A';
    }
    int char1_char2_char3_t = char1_index * 676 + char2_char3_t;
    unsigned int index_value = char1_char2_char3_t;

    if (index_value > N)
    {
        index_value = index_value % N;
    }

    return index_value;
}

// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
    // TODO
    unsigned int newindex;
    // Open the di

1 Answer 1

1

Valgrind is catching something that check50 doesn't look for. There is an issue with your hash function. It can't deal with one-letter words like "a".

Consider that when the word is 1 letter long, word[0] is the letter, word[1] is the EOS char and word[2] is never created. When the following line is executed, word3 is not assigned anything because word[2] doesn't exist. Interestingly, it won't throw an error. (It's based in historical reasons related to c development.)

    char word3 = word[2];

It's unhappy with word3 not being initialized.

The hash function needs additional code to deal with this.

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

3
  • You're a genius bro!! Thank you so much for your help!! Commented Apr 27, 2023 at 3:24
  • This is a good example of why it's critical to thoroughly test code. Some bugs don't produce error conditions. Instead, they can produce incorrect results, unpredictable results (different results for different executions) and leave little or no indication that there's a problem.
    – Cliff B
    Commented Apr 27, 2023 at 7:58
  • You're right! Thanks for sharing your knowledge, you're helping a lot of people! Commented Apr 28, 2023 at 12:31

You must log in to answer this question.

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