- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在一个程序中使用 search.h 库中的 tsearch/tfind/twalk 函数,该程序基本上对文档中的唯一单词进行排序和计数。由于我不知道文档中有多少个单词,因此我首先使用 malloc 为保存所有单词的数组分配一定量的内存,然后使用 realloc 使其更大(如果我已填满) 。然而,realloc 显然破坏了 tsearch 维护的树,并且 twalk 开始返回垃圾节点或者节点的内容被破坏。
结构体定义:
struct word {
char word[MAX_MTEXT];
int occur;
};
struct mymsg {
long mtype;
char mtext[MAX_MTEXT];
int occur;
};
下面的代码是整个子进程代码,还有一些其他处理从消息队列获取单词的内容:
f = 1;
i = 0;
words_entered = 0;
entry = (struct word *) malloc(words_allocated * sizeof(struct word));
while(f) {
if (msgrcv(m_key, &mymsg, sizeof(struct mymsg), (long) getpid(), 0) == -1) {
perror("recieve");
exit(EXIT_FAILURE);
}
//printf("%s recieved\n",mymsg.mtext);
if (mymsg.mtext[0] == '\0') {
//printf("term recv\n");
f = 0;
}
else {
//printf("mtext = %s\n",mymsg.mtext);
memcpy(&entry[i].word,&mymsg.mtext,MAX_MTEXT);
//printf("entry = %s\n",entry[i].word);
entry[i].occur = 1;
//printf("%s entered\n",entry[i].word);
words_entered++;
if (words_entered == words_allocated) {
printf("About to realloc\n\n");
twalk (root, action);
words_allocated = words_allocated *2;
entry = (struct word *) realloc(entry,(size_t) words_allocated * sizeof(struct word));
printf("After realloc\n\n");
twalk (root, action);
}
ptr = tfind(&entry[i],&root,compare);
if (ptr == NULL) {
//printf("null\n");
ptr = tsearch(&entry[i],&root,compare);
//printf("%s added to tree\n",(*ptr)->word);
}
else {
(*ptr)->occur++;
}
i++;
//printf("check\n");
}
}
twalk (root, action);
mymsg.mtype = ret_id;
mymsg.mtext[0] = '\0';
mymsg.occur = 0;
if (msgsnd(m_key, &mymsg, sizeof(mymsg)-sizeof(long), 0) == -1) {
perror("send");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
这是 walk 调用的操作代码:
void action(const void *nodep, VISIT value, int level) {
struct word *w = *((struct word **) nodep);
struct mymsg mymsg;
switch (value) {
case leaf:
case postorder:
printf("%s: %i, level %i\n",w->word, w->occur, level);
mymsg.mtype = ret_id;
strcpy(mymsg.mtext,w->word);
//printf("%s vs %s\n",w->word,mymsg.mtext);
mymsg.occur = w->occur;
if (msgsnd(m_key, &mymsg, sizeof(mymsg)-sizeof(long), 0) == -1) {
perror("send");
exit(EXIT_FAILURE);
}
break;
default:
break;
}
return;
}
这是运行初始分配 5 的结果:
About to realloc
each: 1, level 1
is: 1, level 0
therefore: 1, level 2
translator: 1, level 1
After realloc
Ð3³: 1, level 1
is: 1, level 0
therefore: 1, level 2
translator: 1, level 1
About to realloc
for: 1, level 2
his: 1, level 1
$p : 158343352, level 2
is: 1, level 0
own: 1, level 3
portion;: 1, level 2
responsible: 1, level 3
therefore: 1, level 1
p p rlator: 1, level 2
After realloc
for: 1, level 2
his: 1, level 1
$p : 158343352, level 2
is: 1, level 0
own: 1, level 3
portion;: 1, level 2
responsible: 1, level 3
therefore: 1, level 1
p p rlator: 1, level 2
最佳答案
免责声明:我以前从未使用过 GNU C 的树搜索功能。
现在,如果我查看相应的文档:
—函数:void * tsearch(const void *key, void **rootp, Comparison_fn_t compar)
如果树不包含匹配的条目,则键值将添加到树中。 tsearch 不会不复制 key 指向的对象(因为大小未知,怎么可能呢)。相反,它添加一个引用到该对象,这意味着只要使用树数据结构,该对象就必须可用。
每次 realloc 需要移动内存时,都会使树节点指针无效。另外,您预计 tsearch 不会返回 NULL。
最简单的解决方案是只分配单个字元素,而不是将它们缓冲在数组中。这可能会造成一些速度损失。
如果您确实需要将单词条目排列在 block 中,那么为什么不直接遍历根并在 realloc(entry, ...) !=entry 的情况下更新所有元素指针呢?编辑:根据描述,您可能会在那里遇到 UB。但是,并不能 100% 清楚他们谈论的是一般案例还是 MT 案例。
关于c - Realloc 弄乱了 tsearch 创建的树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21893478/
我正在使用 tsearch() 创建一个二进制文件。创建的树是否自动平衡。我如何验证树是平衡的还是不平衡的。 最佳答案 我前段时间在研究 my own implementation of tsearc
我一直在努力弄清楚 tsearch 库是如何工作的,但我已经到了完全不知所措的地步。这是我的代码: #include #include #include #include #include
我有一个包含多个测试字段的查询,如下所示: SELECT * FROM some-table WHERE field1 ILIKE "%thing%" OR field2 ILIKE "
给定 sizeof(void*) >= sizeof(int),在树中收集整数是否安全 void *map=0; tsearch(42, &map, int_cmp); ? 我遇到了段错误,除了不常用
我在一个程序中使用 search.h 库中的 tsearch/tfind/twalk 函数,该程序基本上对文档中的唯一单词进行排序和计数。由于我不知道文档中有多少个单词,因此我首先使用 malloc
我们正在使用自定义文本搜索配置在德语文本中搜索以正确支持复合词。 字典可以在这里找到:http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/ (
我看到访问所有节点(如果 key 未知)的唯一方法是twalk。是否允许在 twalk 中使用 tdelete?如果不是——如何删除所有节点? (我不想使用不可移植的 GNU 扩展 tdestroy。
我正在使用 glibc tsearch()用于在示例程序中存储动态分配的数据 block 的 API 系列。 我发现当我使用 tsearch() 将几个 malloc()ed block 添加到树中时
我正在将 pg_search 添加到 Rails 应用程序中。我正在按照 github 和 railscast 上的说明进行操作,但遇到了问题。 我正在设置一个多模型搜索,我有一个基本的实现工作。但我
我正在尝试将包含泰语和英语的 MySQL UTF8mb4 数据库转换为 Postgresql。这似乎去好吧,直到我尝试添加 tsearch。让我概述一下所采取的步骤。 安装此泰语解析器 https:/
我是一名优秀的程序员,十分优秀!