0

I try my code here to solve the pset5 - speller question, it seems pretty ok with locally run my valgrind. But when I use check50 to check it. One error(and only 1) happened.

I tried to assigned cursor->word = NULL; , but apprently can not. I have not idea what to do next, please help. Thanks.

Here is my code.

// Implements a dictionary's functionality

#include <stdbool.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.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 = 26;
int words_count = 0;

// Hash table A-Z 的Hash table
node *table[N];

// Returns true if word is in dictionary, else false
bool check(const char *word)
{
    // TODO
    //把 cursor設定到目前hash上的 node
    int hash_index = hash(word);
    node *cursor = table[hash_index];
    //cursor->word = NULL;

    while (cursor != NULL)
    {
        if (strcasecmp(cursor->word, word) == 0)
        {
            return true;
        }

        cursor = cursor->next;
    }
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    // TODO: Improve this hash function
    return (int)(toupper(word[0]) - 'A');
}

// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{

    // TODO
    FILE *dict_file = fopen(dictionary, "r");
    char str[LENGTH + 1];

    if (dict_file == NULL)
    {
        return false;
    }
    while (fscanf(dict_file, "%s", str) != EOF)
    {
        node *new_node = malloc(sizeof(node));
        if (new_node == NULL)
        {
            return false;
        }

        int hash_index = hash(str);

        strncpy(new_node->word, str, strlen(str));
        if (table[hash_index] == NULL)
        {
            new_node->next = NULL;
        }
        else
        {
            new_node->next = table[hash_index];
        }
        table[hash_index] = new_node;

        words_count++;
    }
    fclose(dict_file);
    return true;
}

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

void freenode(node *n)
{
    if (n->next != NULL)
    {
        freenode(n->next);
    }
    free(n);
}

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

Here is my error.

running valgrind --show-leak-kinds=all --xml=yes --xml-file=/tmp/tmpodcs924w -- ./speller substring/dict substring/text...
        checking for output "MISSPELLED WORDS\n\nca\ncats\ncaterpill\ncaterpillars\n\nWORDS MISSPELLED: 4\nWORDS IN DICTIONARY: 2\nWORDS IN TEXT: 6\n"...
        checking that program exited with status 0...
        checking for valgrind errors...
        Conditional jump or move depends on uninitialised value(s): (file: dictionary.c, line: 37)
        Use of uninitialised value of size 8: (file: dictionary.c, line: 37)enter code here

1 Answer 1

0

From man strncpy:

The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.

This strncpy(new_node->word, str, strlen(str)); will not copy the null byte.

AFAIK valgrind reports cursor->word is an unitialised value because it is not a "valid" string (ie not null terminated) when used here if (strcasecmp(cursor->word, word) == 0).

You must log in to answer this question.

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