简体   繁体   中英

CS50 PSET4 Cant free memory in speller

My code works perfectly but valgrind shows that memory allocated to ALL the nodes is still reachable. This causes in failed memory leak test by check50. Here's what valgrind shows-

HEAP SUMMARY:
==14338== in use at exit: 8,013,096 bytes in 143,091 blocks
==14338== total heap usage: 143,096 allocs, 5 frees, 8,023,416 bytes allocated
8,013,096 bytes in 143,091 blocks are still reachable in loss record 1 of 1

here's my code-

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

#include "dictionary.h"

// Represents number of buckets in a hash table
#define N 26

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

// Represents a hash table
node *hashtable[N];

//to count no. of words in the dictionary
int count = 0;

// Hashes word to a number between 0 and 25, inclusive, based on its first letter
unsigned int hash(const char *word)
{
    return tolower(word[0]) - 'a';
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Initialize hash table
    for (int i = 0; i < N; i++)
    {
        hashtable[i] = NULL;
    }

    // Open dictionary
    FILE *file = fopen(dictionary, "r");
    if (file == NULL)
    {
        unload();
        return false;
    }

    // Buffer for a word
    char word[LENGTH + 1];

    // Insert words into hash table
    while (fscanf(file, "%s", word) != EOF)
    {
        // TODO

        //create a new node
        node *newnode = (node *)malloc(sizeof(node));

        //check if new node is allocated memory successsfully
        if (newnode == NULL)
        {
            unload();
            return false;
        }

        //copy word from dictionary to new node
        //newnode->word = word; (X) why?
        strcpy(newnode->word, word);

        //hash the word
        int n = hash(word);

        //add node to the correct bucket
        newnode->next = hashtable[n];
        hashtable[n] = newnode;

        count++;

    }

    // Close dictionary
    fclose(file);

    // Indicate success
    return true;
}

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

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // TODO

    //hash the word to find its bucket
    int n = hash(word);

    //traverse through the bucket
    node *temp = hashtable[n];
    while (temp != NULL)
    {
        if (strcasecmp(temp->word, word) == 0)
        {
            return true;
        }
        temp = temp->next;
    }

    return false;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    // TODO

    node *cursor;

    for (int i = 0; i > 26; i++)
    {
        cursor = hashtable[i];
        while (cursor != NULL)
        {
            node *temp = cursor;
            cursor = cursor->next;
            free(temp);
        }
    }

    return true;
}

Use debug50 with a breakpoint at this line for (int i = 0; i > 26; i++) in unload and step through. What just happened??? There's a typo in the line. Hover below for spoiler.

The loop never process because i is initialized to 0 and i > 26 is false

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