gpt4 book ai didi

c - 哈希表单词在 C 中被覆盖

转载 作者:太空宇宙 更新时间:2023-11-04 02:53:33 27 4
gpt4 key购买 nike

我是第一次使用哈希表,我想我对它们的工作原理有了基本的了解。我正在使用哈希表来检查文件中是否存在某个单词。该程序接受一个“字典”文件和一个单词检查文件。当我有一本小词典时,该程序运行良好,但当我使用非常大的词典时,单词会被覆盖。我希望对原因有所了解。这是我的代码:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <pthread.h>
#include <tgmath.h>
#include <ctype.h>
#include "hashtable_constants.h"


#define HASH_SIZE 500
#define MAX_WORD_SIZE 50

struct hashTable {
int collisions;
char** words;
};

struct hashTable hashTables[HASH_SIZE];

int hashKey(char * str)
{
int key = 0;
for(int j = 0; j <= 51; j++)
{
if(str[j] == '\0')
break;

key += (int)str[j];
}
key = key % HASH_SIZE;
return key;
}

int main(int argc, char** argv)
{

if(argc > 3)
{
fprintf(stderr, "Too many arguments!\n");
return -1;
}
else if(argc < 3)
{
fprintf(stderr, "Not enough arguments!\n");
return -1;
}

FILE *dictionary = fopen(argv[1], "r");
FILE *wordCheck = fopen(argv[2], "r");

if(dictionary == NULL || wordCheck == NULL ) //ensure input file exists
{
fprintf(stderr, "Error accessing input files\n");
return -1;
}

for(int i = 0; i < HASH_SIZE; i++)
{
hashTables[i].collisions = 0;
hashTables[i].words = malloc(HASH_SIZE * MAX_WORD_SIZE);
}

struct stat fileStat1;
struct stat fileStat2;

stat(argv[1], &fileStat1);
stat(argv[2], &fileStat2);

char* dictBuffer = (char*)malloc(fileStat1.st_size + 1);
char* wordCheckBuff = (char*)malloc(fileStat2.st_size + 1);

if (dictBuffer == NULL || wordCheckBuff == NULL)
{
fprintf (stderr, "Memory error");
return -1;
}

fread(dictBuffer, 1, (int)fileStat1.st_size, dictionary);
fread(wordCheckBuff, 1, (int)fileStat2.st_size, wordCheck);

char* word = malloc(MAX_WORD_SIZE + 1);
int count = 0;

for(int i = 0; i < (int)fileStat1.st_size; i++)
{
char c = dictBuffer[i];
if(isspace(c))
{
word[count] = '\0';
char* wordToAdd = word;
int key = hashKey(wordToAdd);
int collisionIndex = hashTables[key].collisions;
hashTables[key].words[collisionIndex] = wordToAdd;
hashTables[key].collisions++;
count = 0;

free(word);
word = malloc(MAX_WORD_SIZE + 1);

//printf("Added: %s to hashtable at key: %d\n",word,key);
}
else
{
word[count] = c;
count++;
}
}

count = 0;

for(int i = 0; i < (int)fileStat2.st_size; i++)
{
char c = wordCheckBuff[i];
if(isspace(c))
{
word[count] = '\0';
char* wordToCheck = word;
int key = hashKey(wordToCheck);
int collisionIndex = hashTables[key].collisions;
int foundWord = 0;

for(int j = 0; j < collisionIndex; j++)
{
if(hashTables[key].words[j] == wordToCheck)
{
printf("%s == %s\n",hashTables[key].words[j], wordToCheck);
foundWord = 1;
break;
}
}

if(foundWord == 0)
printf("Not a word: %s\n", wordToCheck);
/*else
printf("Key: %d -- Is a word: %s\n",key, word);*/

free(word);
word = malloc(MAX_WORD_SIZE + 1);
count = 0;
}
else
{
word[count] = c;
count++;
}
}

for(int i = 0; i < HASH_SIZE; i++)
free(hashTables[i].words);

free(word);
fclose(dictionary);
fclose(wordCheck);

printf("done\n");

return 0;
}

最佳答案

问题在于:

hashTables[key].words[collisionIndex] = wordToAdd;

您将“wordToAdd”添加到表中。

但是 wordToAdd 等于 word。几行之后你打电话

free(word);

因此哈希表现在包含一个指向已释放内存的指针。

这将导致程序中出现各种未定义的行为,很可能还会出现段错误。此外,由于内存现在是“空闲的”,因此很有可能对 malloc 的后续调用可能会再次返回同一个指针——然后您将用另一个词填充它。因此,您会看到字符串被覆盖。

您需要回顾一下您在程序中通常如何使用“malloc”/“free”。如果您希望指针指向有效的字符串,则不能在该字符串的预期生命周期内对该指针调用“free”。

你想要做的是 malloc 每个字符串,并将指针添加到哈希表。然后,当您完成哈希表并且不再需要字符串数据时,然后对其中包含的所有指针调用“free”。在您的情况下,这可能需要在程序执行结束时包含在清理代码中。

关于c - 哈希表单词在 C 中被覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19697451/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com