此函数应该将字典加载到trie中。我想知道字典文件有多大,所以我可以同时calloc
所有内存。这样做的原因是所有内存都靠近在一起,因此可以利用有助于加速搜索的硬件。为此,我找到了2种方法的建议。其中之一就是使用您将在我的代码中看到的sys/stat.h
。
当我运行此代码时,我收到一个"分段错误"我知道这意味着我正在尝试访问我没有获得许可的内存。通过使用GDB,我发现分段错误发生在第116行(又名:读取&#34的行;否则如果(cur-> children [key] == NULL)")我发现当时密钥中的值是12.起初我认为问题是我使用calloc
或sys/stat.h
,因为这些是我所知道的最少关于我使用的两件事。然而,我研究得越多,这似乎就越不可能。如果它不是其中之一那么我甚至不知道在哪里看。
贝娄只是我认为相关的代码:
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/stat.h>
#include "dictionary.h"
typedef struct node
{
bool end[26];
struct node* children[26];
} node;
node* start;
int key;
int last;
int dic_count;
bool load(const char* dictionary)
{
struct stat s;
stat(dictionary, &s);
int size = s.st_size;
dic_count = 0;
int z = 1;
FILE* dic = fopen(dictionary, "r");
if (dic == NULL)
{
return false;
}
start = calloc(size, sizeof(node));
if (start == NULL)
{
return false;
}
int l = 0;
int d;
node* cur = &start[0];
while (0 != (d = fgetc(dic)))
{
int d = fgetc(dic);
if (l > 0)
{
last = key;
}
l = 1;
key = d - 'a';
if (d == '\n')
{
cur->end[last] = true;
cur = &start[0];
dic_count++;
}
else if (cur->children[key] == NULL)
{
node* new = &start[z];
cur->children[key] = new;
z++;
if (cur->children[key] == NULL)
{
return false;
}
cur = cur->children[key];
}
else
{
cur = cur->children[key];
}
}
return true;
}
非常感谢任何帮助。
答案 0 :(得分:3)
您确定您的文件包含二进制0吗?如果您尝试读取直到文件结尾,请针对EOF测试fgetc
结果,而不是0.否则您的循环永远不会终止。
除此之外,您只处理每隔一个字符。
按要求扩展:
来自man fgetc
:
fgetc(),getc()和getchar()将读取的字符作为无符号的char转换为文件末尾的错误或EOF或错误
您可能会将其与fgets
返回值混淆。
while ((ch = fgetc(fp)) != EOF)
安然无恙。再次,可能混淆的根源是
的不健全while (!feof(fp))
现在,关于未处理的字符:你写了
while (0 != (d = fgetc(dic)))
{
int d = fgetc(dic);
代码读取while
表达式中的字符,将其与0进行比较,然后读取(下一个)字符。第一个角色丢失了。