我还在尝试调试我的加载函数,哪个应该加载一个字典文件。我一次又一次地重写我的代码,但没有结果......我知道我们需要有特定的问题,但现在我只有很多问题。所以,我会按照我认为的错误来源。我认为我没有正确地初始化我的两个指针,通过初始化,我的意思是分配内存并为它们定义一个特定类型的值。
在那里,我如何定义和初始化我的节点和指针的结构:
#include "dictionary.h"
#define NB_NODES 27
// define global structure and pointers
typedef struct node
{
bool is_word;
struct node* children[NB_NODES];
} node;
// initialize pointers and variables
node* root = NULL;
node* current = NULL;
int word_counter = 0;
现在,我实现了LOAD:
bool load(const char* dictionary)
{
// open dictionary file
FILE* inptr = fopen(dictionary, "r");
if (inptr == NULL)
{
printf("fail to open dictionary\n");
return false;
}
// initialize tools
root = malloc(sizeof(node));
word_counter = 0;
int index = 0;
current = root;
// looks for word until end reached
for (int c = fgetc(inptr); c != EOF; c = fgetc(inptr))
{
// looking words one by one
if (c != '\n')
{
if (c == '\'')
{
index = 26;
if (current->children[index] == NULL)
{
current->children[index] = calloc(1, sizeof(node));
// test
if (current->children[index] == NULL)
{
printf("error with apostrophe");
return 1;
}
}
}
else
{
index = c - 'a';
if (current->children[index] == NULL)
{
current->children[index] = calloc(1, sizeof(node));
// test
if (current->children[index] == NULL)
{
printf("error with characters");
return 1;
}
}
}
// update current pointer to the next node
current = current->children[index];
}
else if (c == '\n')
{
// new word found
if (current->is_word == false)
{
current->is_word = true;
word_counter++;
current = root;
}
// duplicate word
else
{
current = root;
}
}
// character not found
else
{
printf("character not found");
return 2;
}
}
fclose(inptr);
return true;
}
所以在我的头文件中,我声明我的指针等于NULL,并让所有子函数(全局变量)都可以访问它们。之后,在LOAD的顶部,我将节点的内存大小分配给指针根目录。我已经尝试了很多方法来编写代码,但是共享的方法似乎是最符合逻辑的。
我也怀疑在找到完整单词后重新初始化根指针的方式。可能是这样做,我做的方式,我"失去"刚刚找到这个词的轨迹?
在这种情况下,我们非常感谢帮助继续调试,因为这不是我唯一的问题!
这是我在尝试运行speller时遇到的主要错误,主函数调用load:
jharvard@appliance (~/Dropbox/pset5): ./speller ~cs50/pset5/dictionaries/small/austinpowers.txt
Could not open /home/cs50/pset5/dictionaries/small/austinpowers.txt.
*** Error in `./speller': double free or corruption (!prev): 0x094302d8 ***
Aborted (core dumped)
jharvard@appliance (~/Dropbox/pset5):
我还在gdb中启动了拼写错误并得到了这个错误:
jharvard@appliance (~/Dropbox/pset5): gdb ./speller
Reading symbols from ./speller...done.
(gdb) run ~cs50/pset5/dictionaries/small/austinpowers.txt
Starting program: /home/jharvard/Dropbox/pset5/speller ~cs50/pset5/dictionaries/small/austinpowers.txt
Could not open /home/cs50/pset5/dictionaries/small/austinpowers.txt.
*** Error in `/home/jharvard/Dropbox/pset5/speller': double free or corruption (!prev): 0x0804c2d8 ***
Program received signal SIGABRT, Aborted.
0xb7fdd428 in __kernel_vsyscall ()
(gdb)
奇怪的是,当我在gdb中一步一步地前进时,我可以通过我的加载循环而不会收到失败......
我的代码是UNLOAD(已修订):
bool unload(void)
{
// recursive_free prototype
void recursive_free (node* node_to_free);
recursive_free(root);
if (root == NULL)
{
return true;
}
else return false;
}
void recursive_free (node* node_to_free)
{
for (int i = 0; i < NB_NODES; i++)
{
// node created to assign memory to free if children found
node* temp;
// if children found
if (node_to_free->children[i])
{
temp = node_to_free;
node_to_free = node_to_free->children[i];
free(temp);
recursive_free(node_to_free);
}
else free(node_to_free);
}
}
如果需要更多东西来帮助我,请问,我会补充。谢谢你的时代。
答案 0 :(得分:0)
您的加载功能看起来不错。在卸载函数中,您必须首先下降所有节点,然后释放底部节点,然后再升级一级等等:
void recursive_free (node* node_to_free)
{
for (int i = 0; i < NB_NODES; i++)
{
// if children found
if (node_to_free->children[i])
{
recursive_free(node_to_free->children[i]);
}
}
free(node_to_free);
}