简体   繁体   中英

CS50 Pset5 Speller - Valgrind error: Conditional jump or move depends on uninitialised value(s)

When I run this code I get the errors:

==25659== ERROR SUMMARY: 1000 errors from 1 contexts (suppressed: 0 from 0)

with details from help50:

==25659== Conditional jump or move depends on uninitialized value(s)

Looks like you're trying to use a variable that might not have a value? Take a close look at line 140.

Line 140 belongs to unload function. Here's my code:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include <cs50.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;

// Assign number of buckets in hash table
const unsigned int N = 1000;

// Hash table
node *table[N];

// Initialize hash table word count
int counter = 0;

// Returns true if word is in dictionary, else false
bool check(const char *word)
{
    // TODO
    int index = hash(word);

    // check if word is in dictionary
    node *cursor = table[index];

    // Traverse linked list, looking for word
    while (cursor != NULL)
    {
        if (strcasecmp(word, cursor->word) == 0)
        {
            return true;
        }

        cursor = cursor->next;
    }

    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    // Sum up ASCII values of all characters in the word
    long sum = 0;
    int index = 0;
    for (int i = 0; i < strlen(word); i++)
    {
        sum += tolower(word[i]);
    }
    index = sum % N;
    return index;
}

// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
   // Open dictionary file
    FILE *current_dictionary = fopen(dictionary, "r");

    // Check if return value is NULL
    if (current_dictionary == NULL)
    {
        printf("Could not open %s\n", dictionary);
        return false;
    }

    // Read strings from file one at a time until the end of file
    char word[LENGTH + 1];

    while (fscanf(current_dictionary, "%s", word) != EOF)
    {
        // Create a new node for each word
        node *new_word = malloc(sizeof(node));

        // Check if return value is NULL
        if (new_word == NULL)
        {
            unload();
            return false;
        }

        // Copy and insert node into hash table
        strcpy(new_word->word, word);

        // Hash word to obtain a hash value
        int index = hash(word);

        // Initialize head to point to hash table index
        node *head = table[index];

        if (head == NULL)
        {
            table[index] = new_word;
            counter++;
        }
        else
        {
           new_word->next = table[index];
            table[index] = new_word;
            counter++;
        }
    }

    // Close file
    fclose(current_dictionary);
    return true;
}

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


// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
    for (int i = 0; i < N; i++)
    {
        node *cursor = table[i];

    // Free linked lists
        while (cursor != NULL) // line 140
        {
            node *tmp = cursor;
            cursor = cursor->next;
            free(tmp);
        }
    }

    return true; 
}

Interesting, 1000 errors and 1000 buckets in the hash table.

One node in each hash bucket,the first one inserted, has an unitialized next . Subsequent inserts initialize it here new_word->next = table[index];

Program could use calloc when creating new_node to initialize all bytes to 0. Or set new_node->next to NULL after the node is (successfully) created.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM