我已经阅读了有关pset5 Valgrind内存错误的其他线程,但这对我没有帮助。我收到了0次泄漏,但是相反:
== 1917 ==条件跳转或移动取决于未初始化的值 看起来您正在尝试使用可能没有值的变量?仔细查看dictionary.c的第34行。
错误指向第34行,它是:lower [i] = tolower(word [i]);
为提供上下文,下面的代码尝试检查已上传到哈希表的字典中是否存在某个单词。我正在尝试将所需的单词转换为小写,因为所有的词典单词也都是小写的,因此它们的哈希值是相同的。该程序成功完成了所有任务,但随后偶然发现了这些内存错误。
有人暗示为什么瓦尔格朗德生我的气吗?谢谢!
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char lower[LENGTH + 1];
//Converts word to lower so the hashes of the dictionary entry and searched word would match
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
// Creates node from the given bucket
node *tmp = table[hash(lower)];
// Traverses the linked list
while (tmp != NULL)
{
if (strcasecmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
下面是整个dictionary.c文件:
// Implements a dictionary's functionality
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <stdio.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 26^3
const unsigned int N = 17576;
// Hash table
node *table[N];
int count = 0;
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char lower[LENGTH + 1];
//Converts word to lower so the hashes of the dictionary entry and searched word would match
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
// Creates node from the given bucket
node *tmp = table[hash(lower)];
// Traverses the linked list
while (tmp != NULL)
{
if (strcasecmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// Modified hash function by Dan Berstein taken from http://www.cse.yorku.ca/~oz/hash.html
unsigned int hash = 5381;
int c;
while ((c = *word++))
{
hash = (((hash << 5) + hash) + c) % N; /* hash * 33 + c */
}
return hash;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
FILE *inptr = fopen(dictionary, "r");
if (dictionary == NULL)
{
printf("Could not load %s\n.", dictionary);
return false;
}
// Create a char array to temporarily hold the new word (r stands for read)
char r_word[N+1];
// Until the end of file
while (fscanf(inptr, "%s", r_word) != EOF)
{
// Increments count
count++;
// Create a node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
unload();
return false;
}
strcpy(new_node->word, r_word);
// Hash the node
int index = hash(new_node->word);
// Places the node at the right index
new_node->next = table[index];
table[index] = new_node;
}
fclose(inptr);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
if (&load == false)
{
return '0';
}
else
{
return count;
}
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// Interates over the array
for (int i = 0; i < N; i++)
{
node *head = table[i];
while (head != NULL)
{
node *tmp = head;
head = head->next;
free(tmp);
}
}
return true;
}
答案 0 :(得分:1)
此循环迭代word
-
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
除非您查看如何创建word
-
while (fscanf(inptr, "%s", r_word) != EOF)
{
// Increments count
count++;
// Create a node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
unload();
return false;
}
strcpy(new_node->word, r_word);
注意,变量r_word
的长度可能不完全为LENGTH + 1
。因此,您在word
中真正拥有的字符数为N,其中N不一定是 LENGTH + 1
,
因此,对于短于0 -> LENGTH + 1
的单词,遍历整个LENGTH + 1
会成为问题。您正在遍历没有值的数组插槽,它们具有垃圾值。
有什么解决方案?这就是为什么c字符串具有\0
-
for (int i = 0; word[i] != '\0'; i++)
{
lower[i] = tolower(word[i]);
}
这将在到达NULL字符后立即停止循环,您必须已经学习过NULL字符,它标志着字符串的末尾-aka字符数组。
您的代码中可能仍然存在更多错误。但是对于您的特定问题-超越界限的阅读就是答案。