cs50拼写器一直提示free(): double free detected in tcache 2
cs50 speller keeps prompting free(): double free detected in tcache 2
我已经研究了这个问题集很长时间了,代码似乎是错误的,但我找不到解决方案。我一直在比较我的代码和其他人的代码,但我仍然不知道我哪里错了。如果您能为我提供一些解决此问题的方法,非常感谢您的帮助。它一直提示我 free(): double free detected in tcache 2
但我似乎找不到我的错误。
// Implements a dictionary's functionality
#include <stdbool.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.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 = 50;
// Hash table
node *table[N];
//word count
int count = 0;
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
// TODO
bool found = false;
node *current = table[hash(word)];
while (current != NULL)
{
if (strcasecmp(current -> word, word) == 0)
{
found = true;
}
else if(current -> next != NULL)
{
current = current -> next;
}
else
{
return false;
}
}
return found;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO
unsigned long hash = 5381;
int c;
while ((c = toupper(*word++)))
{
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash % N;
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// TODO
FILE *infile = fopen(dictionary, "r");
if (infile == NULL)
{
return false;
}
char buffer[LENGTH+1];
while (fscanf(infile, "%s", buffer) != EOF)
{
node *n = malloc(sizeof(node));
strcpy(n -> word, buffer);
n -> next = table[hash(buffer)];
table[hash(buffer)] = n;
count++;
free(n);
}
fclose(infile);
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// TODO
return count;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
// TODO
int num = count;
for (int i = 0; i < N ; i++)
{
node *current = table[i];
while (current != NULL)
{
node *temp = current;
current = current -> next;
free(temp);
num--;
}
}
if (num == 0)
{
return true;
}
else
{
return false;
}
}
这个while循环中free的调用次数
while (fscanf(infile, "%s", buffer) != EOF)
{
node *n = malloc(sizeof(node));
strcpy(n -> word, buffer);
n -> next = table[hash(buffer)];
table[hash(buffer)] = n;
count++;
free(n);
}
没有意义。您立即删除了(使用指针 n
的 node
类型的对象)您试图添加到 table 的内容(分配给类型 [= 的对象的有效地址) 14=]).结果 table 位置 hash(buffer)
的元素设置为
table[hash(buffer)] = n;
有一个无效值,因为它是该语句中已删除节点的地址
free(n);
因此在函数 unload
中,这个无效地址将再次用于释放函数 load
中已经释放的内存。
注意你没有像你在评论“for node n
”中写的那样分配内存。 n
只是指向类型节点的已分配未命名对象的指针。所以你没有在这条语句
中释放指针n
本身
free(n);
您正在使用指针 n
释放类型节点的分配对象。因此,所有指向类型 node
的已分配对象的指针都变得无效。
我已经研究了这个问题集很长时间了,代码似乎是错误的,但我找不到解决方案。我一直在比较我的代码和其他人的代码,但我仍然不知道我哪里错了。如果您能为我提供一些解决此问题的方法,非常感谢您的帮助。它一直提示我 free(): double free detected in tcache 2
但我似乎找不到我的错误。
// Implements a dictionary's functionality
#include <stdbool.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.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 = 50;
// Hash table
node *table[N];
//word count
int count = 0;
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
// TODO
bool found = false;
node *current = table[hash(word)];
while (current != NULL)
{
if (strcasecmp(current -> word, word) == 0)
{
found = true;
}
else if(current -> next != NULL)
{
current = current -> next;
}
else
{
return false;
}
}
return found;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO
unsigned long hash = 5381;
int c;
while ((c = toupper(*word++)))
{
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash % N;
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// TODO
FILE *infile = fopen(dictionary, "r");
if (infile == NULL)
{
return false;
}
char buffer[LENGTH+1];
while (fscanf(infile, "%s", buffer) != EOF)
{
node *n = malloc(sizeof(node));
strcpy(n -> word, buffer);
n -> next = table[hash(buffer)];
table[hash(buffer)] = n;
count++;
free(n);
}
fclose(infile);
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// TODO
return count;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
// TODO
int num = count;
for (int i = 0; i < N ; i++)
{
node *current = table[i];
while (current != NULL)
{
node *temp = current;
current = current -> next;
free(temp);
num--;
}
}
if (num == 0)
{
return true;
}
else
{
return false;
}
}
这个while循环中free的调用次数
while (fscanf(infile, "%s", buffer) != EOF)
{
node *n = malloc(sizeof(node));
strcpy(n -> word, buffer);
n -> next = table[hash(buffer)];
table[hash(buffer)] = n;
count++;
free(n);
}
没有意义。您立即删除了(使用指针 n
的 node
类型的对象)您试图添加到 table 的内容(分配给类型 [= 的对象的有效地址) 14=]).结果 table 位置 hash(buffer)
的元素设置为
table[hash(buffer)] = n;
有一个无效值,因为它是该语句中已删除节点的地址
free(n);
因此在函数 unload
中,这个无效地址将再次用于释放函数 load
中已经释放的内存。
注意你没有像你在评论“for node n
”中写的那样分配内存。 n
只是指向类型节点的已分配未命名对象的指针。所以你没有在这条语句
n
本身
free(n);
您正在使用指针 n
释放类型节点的分配对象。因此,所有指向类型 node
的已分配对象的指针都变得无效。