hsearch中的分段错误

时间:2014-09-15 13:45:31

标签: c linux hash segmentation-fault

我在源代码中使用(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) 

5 个答案:

答案 0 :(得分:1)

搜索时,您应设置ep2.key以搜索不是ep2.data的条目。因此,请将代码更新为

//--v
ep2.key = (void *) "cpe1";
ep_ptr = hsearch(ep2, FIND);

由于您尚未设置ep2.keyhsearch()函数会尝试访问未初始化的指针,从而导致分段错误。

答案 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)

我注意到了一些事情。

  1. 您在循环中重复分配ptr,但您没有释放它。那就是内存泄漏。

  2. ep.data的数据类型是什么?为什么必须转换为(void *)?然后你又将它转换为(char *) !!为什么??如果您data已经char类型,那么为什么需要重复转换为(void *)

  3. 修复这些错误,然后尝试一下。

答案 4 :(得分:-2)

该行看起来不正确:
ep2.data = (void *) "cpe1";

我找到了ENTRY的定义,因此您可以更好地了解其无法按预期工作的原因:
ep2.data = (void *) "cpe1"; 在复制其中的所有字节之前,您需要先分配密钥和数据。