c中一个块的内存泄漏(cs50 pset5,拼写字母)

问题描述 投票:0回答:1

我几乎已经完成了CS50的拼写分配,但是由于某种原因,我的一个存储块无法用于我的unload功能。这是下面的代码:

// Implements a dictionary's functionality

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

#include "dictionary.h"

// 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 = 50000;

// Hash table
node *table[N];

// initialize hash table (set all values to NULL)
// reference video: https://youtu.be/2Ti5yvumFTU
void init_table()
{
    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }
}

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // turn all letters of word into lowercase, add NUL to indicate end of word
    // implemented from: https://cs50.stackexchange.com/questions/28984/more-help-with-speller-check
    int len = strlen(word);
    char lowerWord[len + 1];
    for (int i = 0; i < len; i++)
    {
        lowerWord[i] = tolower(word[i]);
    }
    lowerWord[len] = '\0';

    // hash the lowerWord as index, store its table[index] in node cursor
    int index = hash(lowerWord);
    node *cursor = table[index];

    // loop through linked list until the end, at NULL
    while (cursor != NULL)
    {
        if (strcasecmp(cursor->word, lowerWord) == 0)
        {
            return true;
        }
        cursor = cursor->next;
    }
    return false;
}

// Hashes word to a number
// hash function: djb2
// retrieved from http://www.cse.yorku.ca/~oz/hash.html
unsigned int hash(const char *word)
{
    unsigned int hash_value = N;
    int c;

    while ((c = *word++))
    {
        hash_value = ((hash_value << 5) + hash_value) + c; /* hash * 33 + c */
    }
    return hash_value % N;
}

// incremental int for size function
int word = 0;

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // open dictionary file, check if NULL
    FILE *dict_file = fopen(dictionary, "r");
    if (dict_file == NULL)
    {
        return false;
    }

    init_table();

    // create char array for each dictionary word (max length + nul)
    char dict_word[LENGTH + 1];

    // scan until end of file
    while (fscanf(dict_file, "%s", dict_word) != EOF)
    {
            // create a node n for each word and copy string into it
            node *n = malloc(sizeof(node));
            if (n == NULL)
            {
                return false;
            }
            strcpy(n->word, dict_word);

            // hash the word and store as index (which tells which linked list to use)
            int index = hash(n->word);

            // if table[index] is NULL, set it as node n, set next node as NULL
            if (table[index] == NULL)
            {
                table[index] = n;
                n->next = NULL;
            }
            // otherwise set next node as table[index], table[index] as current node n
            else
            {
                n->next = table[index];
                table[index] = n;
            }
            word++;
    }
    size();
    return true;
}

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

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    for (int i = 0; i < N; i++)
    {
        node *cursor = table[i];
        while (cursor != NULL)
        {
            node *temp = cursor;
            cursor = cursor->next;
            free(temp);
        }
    }
    return true;
}

[当我运行Valgrind来检查输出(使用此输入:help50 valgrind ./speller texts/cat.txt)时,我看到552 bytes in 1 blocks仍可访问,并且我的总堆使用量为143,096 allocs, 143,095 frees。这是完整的Valgrind输出:

==27463== Memcheck, a memory error detector
==27463== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==27463== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==27463== Command: ./speller texts/cat.txt
==27463== 

MISSPELLED WORDS


WORDS MISSPELLED:     0
WORDS IN DICTIONARY:  143091
WORDS IN TEXT:        6
TIME IN load:         1.28
TIME IN check:        0.00
TIME IN size:         0.00
TIME IN unload:       0.18
TIME IN TOTAL:        1.46

==27463== 
==27463== HEAP SUMMARY:
==27463==     in use at exit: 552 bytes in 1 blocks
==27463==   total heap usage: 143,096 allocs, 143,095 frees, 8,023,416 bytes allocated
==27463== 
==27463== 552 bytes in 1 blocks are still reachable in loss record 1 of 1
==27463==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27463==    by 0x5258E49: __fopen_internal (iofopen.c:65)
==27463==    by 0x5258E49: fopen@@GLIBC_2.2.5 (iofopen.c:89)
==27463==    by 0x40126E: load (dictionary.c:87)
==27463==    by 0x4009B4: main (speller.c:40)
==27463== 
==27463== LEAK SUMMARY:
==27463==    definitely lost: 0 bytes in 0 blocks
==27463==    indirectly lost: 0 bytes in 0 blocks
==27463==      possibly lost: 0 bytes in 0 blocks
==27463==    still reachable: 552 bytes in 1 blocks
==27463==         suppressed: 0 bytes in 0 blocks
==27463== 
==27463== For counts of detected and suppressed errors, rerun with: -v
==27463== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
c memory-management memory-leaks heap-memory cs50
1个回答
0
投票

fclose(dict_file)函数末尾代码缺少load

© www.soinside.com 2019 - 2024. All rights reserved.