我被困了2-3周。我想我需要帮助。 这是我的代码
// Implements a dictionary's functionality
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.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 = 2600;
// Hash table
node *table[N];
// Counter for size
int counter;
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// Making a pointer to the file which contains the dictionary
FILE *file = fopen(dictionary, "r");
// Declaring a temporary word to store the copied word from the dictionary
char w[LENGTH + 1];
// Check if memory is available
if (file == NULL)
return false;
// Clearing the table to NULL
for (int i = 0; i < N; i++)
{
table[i] = NULL;
}
// It will run until the file is finished
while(fscanf(file, "%s", w) != EOF)
{
node *n = malloc(sizeof(node));
// Check if memory is available
if (n == NULL)
return false;
// Copy the word from the dictionary to w
strcpy(n -> word, w);
// Store the index at which the word should be stored
int pos = hash(n -> word);
// Set the 'next' value of 'n' to point at the head of the list
n -> next = table[pos];
table[pos] = n;
// Increase the counter per word copied from the dictionary
counter++;
// Free the allocated memory
free(n);
}
size();
// close the file
fclose(file);
return true;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// Idea inspired from "https://www.youtube.com/watch?v=2Ti5yvumFTU&t=782s"
int sum = 0;
for (int i = 0, len = strlen(word); i < len; i++)
{
sum += (int) word[i];
}
return (sum % N);
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
return counter;
}
// Returns true if word is in dictionary else false
bool check(const char *word)
{
// Make a temporary string to store the word to be checked
char *temp = malloc(sizeof(char) * (LENGTH + 1));
for (int i = 0; i < LENGTH; i++)
{
temp[i] = tolower(word[i]);
}
// Getting the hash value of the word to be searched
int h = hash(temp);
node *ptr = malloc(sizeof(node));
temp[LENGTH] = '\0';
// ptr searches table where the word would be if it exists
ptr = table[h];
while (ptr != NULL)
{
if (strcasecmp(temp, ptr -> word) == 0)
{
return true;
}
ptr = ptr -> next;
}
return false;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i < N; i++)
{
node *ptr = table[i];
// Free each linked list
while (ptr != NULL)
{
node *tmp = ptr;;
ptr = ptr->next;
free(tmp);
}
}
return true;
}
这是help50 valgrind消息
==9041== Memcheck, a memory error detector
==9041== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9041== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9041== Command: ./speller texts/cat.txt
==9041==
MISSPELLED WORDS
A
==9041== Invalid read of size 1
==9041== at 0x4C3361E: strcasecmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x401294: check (dictionary.c:111)
==9041== by 0x400C89: main (speller.c:112)
==9041== Address 0x63233c0 is 0 bytes inside a block of size 56 free'd
==9041== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x401162: load (dictionary.c:70)
==9041== by 0x400964: main (speller.c:40)
==9041== Block was alloc'd at
==9041== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x4010EC: load (dictionary.c:51)
==9041== by 0x400964: main (speller.c:40)
==9041==
==9041== Invalid read of size 8
==9041== at 0x4012BD: check (dictionary.c:117)
==9041== by 0x400C89: main (speller.c:112)
==9041== Address 0x63233f0 is 48 bytes inside a block of size 56 free'd
==9041== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x401162: load (dictionary.c:70)
==9041== by 0x400964: main (speller.c:40)
==9041== Block was alloc'd at
==9041== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x4010EC: load (dictionary.c:51)
==9041== by 0x400964: main (speller.c:40)
==9041==
==9041== Invalid free() / delete / delete[] / realloc()
==9041== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x4012AF: check (dictionary.c:114)
==9041== by 0x400C89: main (speller.c:112)
==9041== Address 0x5816670 is 0 bytes inside a block of size 56 free'd
==9041== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x401162: load (dictionary.c:70)
==9041== by 0x400964: main (speller.c:40)
==9041== Block was alloc'd at
==9041== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x4010EC: load (dictionary.c:51)
==9041== by 0x400964: main (speller.c:40)
==9041==
==9041== Invalid read of size 8
==9041== at 0x401333: unload (dictionary.c:134)
==9041== by 0x400E09: main (speller.c:152)
==9041== Address 0x55cc320 is 48 bytes inside a block of size 56 free'd
==9041== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x401162: load (dictionary.c:70)
==9041== by 0x400964: main (speller.c:40)
==9041== Block was alloc'd at
==9041== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x4010EC: load (dictionary.c:51)
==9041== by 0x400964: main (speller.c:40)
==9041==
==9041== Invalid free() / delete / delete[] / realloc()
==9041== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x401346: unload (dictionary.c:135)
==9041== by 0x400E09: main (speller.c:152)
==9041== Address 0x55cc2f0 is 0 bytes inside a block of size 56 free'd
==9041== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x401162: load (dictionary.c:70)
==9041== by 0x400964: main (speller.c:40)
==9041== Block was alloc'd at
==9041== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x4010EC: load (dictionary.c:51)
==9041== by 0x400964: main (speller.c:40)
==9041==
WORDS MISSPELLED: 1
WORDS IN DICTIONARY: 143091
WORDS IN TEXT: 6
TIME IN load: 1.57
TIME IN check: 0.00
TIME IN size: 0.00
TIME IN unload: 0.16
TIME IN TOTAL: 1.74
==9041==
==9041== HEAP SUMMARY:
==9041== in use at exit: 336 bytes in 6 blocks
==9041== total heap usage: 143,108 allocs, 286,198 frees, 8,024,028 bytes allocated
==9041==
==9041== 336 bytes in 6 blocks are definitely lost in loss record 1 of 1
==9041== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x401260: check (dictionary.c:104)
==9041== by 0x400C89: main (speller.c:112)
==9041==
==9041== LEAK SUMMARY:
==9041== definitely lost: 336 bytes in 6 blocks
==9041== indirectly lost: 0 bytes in 0 blocks
==9041== possibly lost: 0 bytes in 0 blocks
==9041== still reachable: 0 bytes in 0 blocks
==9041== suppressed: 0 bytes in 0 blocks
==9041==
==9041== For counts of detected and suppressed errors, rerun with: -v
==9041== ERROR SUMMARY: 286630 errors from 6 contexts (suppressed: 0 from 0)
Asking for help...
==9041== 336 bytes in 6 blocks are definitely lost in loss record 1 of 1
==9041== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9041== by 0x401260: check (dictionary.c:104)
==9041== by 0x400C89: main (speller.c:112)
Looks like your program leaked 336 bytes of memory. Did you forget to free memory that you allocated via malloc? Take a closer look at line 104 of dictionary.c.
还有check50消息
:) dictionary.c,dictionary.h和Makefile存在
:)拼写器编译
:(可处理正确预期的最基本单词“ MISSPELLED WOR ...”,而不是“ MISSPELLED WOR ...”
:)处理最小长度(1个字符)的单词
:)处理最大长度(45个字符)的单词
:)正确处理带有撇号的单词
:(拼写检查不区分大小写,应为“ MISSPELLED WOR ...”,而不是“ MISSPELLED WOR ...”
:(处理正确预期为“ MISSPELLED WOR ...”而不是“ MISSPELLED WOR ...”的子字符串
:|程序没有内存,直到皱着眉头,才能检查错误
答案 0 :(得分:0)
Valgrind没有报告真正原因。有问题的代码:
while(fscanf(file, "%s", w) != EOF)
{
node *n = malloc(sizeof(node));
// Free the allocated memory
free(n);
}
您只能在free
函数中unload
来使用它们。