在树结构中加载和卸载字典的问题 - C 编程
Issues to load a dictionary in a tree structure and unload it - C programming
我仍在尝试调试我的加载函数,该函数应该加载字典文件。我一次又一次地重写我的代码,但没有结果……我知道我们需要有具体的问题,但现在我只有这么多问题。所以,我会继续我认为是我错误的根源。我想我没有正确初始化我的两个指针,通过初始化,我的意思是分配内存并将它们定义为特定类型的值。
在那里,我如何定义和初始化我的节点和指针的结构:
#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;
}
所以在我的 headers 语句中,我将我的指针声明为 NULL,并让所有子函数(全局变量)都可以访问它们。之后,在 LOAD 的顶部,我将节点的内存大小分配给我的指针根。我尝试了很多方法来对此进行编码,但共享的方法似乎是最合乎逻辑的。
我也对找到一个完整的单词后重新初始化根指针的方式有疑问。可能是在这样做,我这样做的方式,我 "lost" 刚刚找到单词的轨迹?
在这种情况下,如果能继续调试,我们将不胜感激,因为这不是我唯一的问题!
这是我在尝试 运行 拼写器时遇到的主要错误,主函数调用加载:
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 (REVISED) 代码:
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);
}
}
如果需要更多的东西来帮助我,尽管问,我会添加。感谢您的光临。
您的加载函数看起来没问题。在你的卸载函数中,你必须首先下降所有节点,然后释放底部节点,然后再向上一层等等:
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);
}
我仍在尝试调试我的加载函数,该函数应该加载字典文件。我一次又一次地重写我的代码,但没有结果……我知道我们需要有具体的问题,但现在我只有这么多问题。所以,我会继续我认为是我错误的根源。我想我没有正确初始化我的两个指针,通过初始化,我的意思是分配内存并将它们定义为特定类型的值。
在那里,我如何定义和初始化我的节点和指针的结构:
#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;
}
所以在我的 headers 语句中,我将我的指针声明为 NULL,并让所有子函数(全局变量)都可以访问它们。之后,在 LOAD 的顶部,我将节点的内存大小分配给我的指针根。我尝试了很多方法来对此进行编码,但共享的方法似乎是最合乎逻辑的。
我也对找到一个完整的单词后重新初始化根指针的方式有疑问。可能是在这样做,我这样做的方式,我 "lost" 刚刚找到单词的轨迹?
在这种情况下,如果能继续调试,我们将不胜感激,因为这不是我唯一的问题!
这是我在尝试 运行 拼写器时遇到的主要错误,主函数调用加载:
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 (REVISED) 代码:
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);
}
}
如果需要更多的东西来帮助我,尽管问,我会添加。感谢您的光临。
您的加载函数看起来没问题。在你的卸载函数中,你必须首先下降所有节点,然后释放底部节点,然后再向上一层等等:
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);
}