我在源代码中使用(http://linux.die.net/man/3/hsearch)。我编写了一个非常基本的代码来测试哈希函数(不想通过编写我自己的哈希实现重新发明轮子)。我发现它在搜索例程中因分段错误而崩溃。
知道它崩溃的原因吗?
#include <stdio.h>
#include <search.h>
#include <stdlib.h>
char *data[] = {
"cpe1","cpe2","cpe3","cpe4","cpe5","cpe6","cpe7","cpe8","cpe9","cpe10","cpe11","cpe12","cpe13"};
int main()
{
ENTRY ep, ep1, *ep_ptr, ep2;
int loop;
char *ptr;
char input[100];
hcreate (30);
for (loop=0; loop<13;loop++)
{
ptr = malloc (100);
sprintf (ptr, "%d.%d.%d.%d%c", loop+1, loop*2, loop*3, loop, '\0');
ep.key = data[loop];
ep.data = (void *) ptr;
printf ("%s --> %s\n", ep.key, (char *) ep.data);
ep_ptr = hsearch(ep, ENTER);
}
ep2.data = (void *) "cpe1";
ep_ptr = hsearch(ep2, FIND);
printf("%9.9s -> %9.9s: %s\n", ep2.key,
ep_ptr ? ep_ptr->key : "NULL", ep_ptr ? (char *)(ep_ptr->data) : "NULL");
return 0;
}
输出:
(gdb) r
Starting program: /home/globus/code/cpe/a.out
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
cpe1 --> 1.0.0.0
cpe2 --> 2.2.3.1
cpe3 --> 3.4.6.2
cpe4 --> 4.6.9.3
cpe5 --> 5.8.12.4
cpe6 --> 6.10.15.5
cpe7 --> 7.12.18.6
cpe8 --> 8.14.21.7
cpe9 --> 9.16.24.8
cpe10 --> 10.18.27.9
cpe11 --> 11.20.30.10
cpe12 --> 12.22.33.11
cpe13 --> 13.24.36.12
Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:32
32 ../sysdeps/x86_64/multiarch/../strlen.S: No such file or directory.
(gdb) bt
#0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:32
#1 0x00007ffff7b0ba71 in __GI_hsearch_r (item=..., action=FIND, retval=0x7fffffffdfd8,
htab=0x7ffff7dd67d0) at hsearch_r.c:149
#2 0x00007ffff7b0b92e in hsearch (item=..., action=<optimized out>)
at hsearch.c:34
#3 0x00000000004007a0 in main () at hash_test.c:32
(gdb)
答案 0 :(得分:1)
搜索时,您应设置ep2.key
以搜索不是ep2.data
的条目。因此,请将代码更新为
//--v
ep2.key = (void *) "cpe1";
ep_ptr = hsearch(ep2, FIND);
由于您尚未设置ep2.key
,hsearch()
函数会尝试访问未初始化的指针,从而导致分段错误。
答案 1 :(得分:1)
ep2.data = (void *) "cpe1";
ep_ptr = hsearch(ep2, FIND);
第一个声明存在错误,您需要将键设置为您想要查找的内容,而不是数据。
由于您没有将密钥设置为任何内容,因此它具有一些任意值(它不是静态存储持续时间,因此它未初始化)。
然后,hsearch
然后在其上运行字符串函数(例如strlen
),这就是您遇到崩溃的原因:
Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2 () at ...
^^^^^^^^^^^^^
(running string function on non-string).
您的代码应该是:
ep2.key = (void *) "cpe1";
ep_ptr = hsearch(ep2, FIND);
答案 2 :(得分:0)
在最后一个printf中,ep2.key未初始化
答案 3 :(得分:0)
我注意到了一些事情。
您在循环中重复分配ptr
,但您没有释放它。那就是内存泄漏。
ep.data
的数据类型是什么?为什么必须转换为(void *)
?然后你又将它转换为(char *)
!!为什么??如果您data
已经char
类型,那么为什么需要重复转换为(void *)
?
修复这些错误,然后尝试一下。
答案 4 :(得分:-2)
该行看起来不正确:
ep2.data = (void *) "cpe1";
我找到了ENTRY的定义,因此您可以更好地了解其无法按预期工作的原因:
ep2.data = (void *) "cpe1";
在复制其中的所有字节之前,您需要先分配密钥和数据。