分割。strcmp[C]

分割。strcmp[C],c,segmentation-fault,strcmp,C,Segmentation Fault,Strcmp,我有一个格式为:[姓名][编号][金额]的文件 数字作为字符串。我在一个strcmp里用它。 问题是我有一个分段错误。我知道,在大多数情况下,当strcmp标记分段错误时,意味着其中一个参数为null或找不到其“end”(“\0”)。 我与gdb进行了核实,我无法确定这是否是问题所在。请看: > (gdb) bt full > #0 0x08048729 in lookup (hashtable=0x804b008, hashval=27, > number=0x8

我有一个格式为:[姓名][编号][金额]的文件 数字作为字符串。我在一个strcmp里用它。 问题是我有一个分段错误。我知道,在大多数情况下,当strcmp标记分段错误时,意味着其中一个参数为null或找不到其“end”(“\0”)。 我与gdb进行了核实,我无法确定这是否是问题所在。请看:

> (gdb) bt full
> #0  0x08048729 in lookup (hashtable=0x804b008, hashval=27, 
>     number=0x804b740 "6900101001") 
>         list = 0xffffffff
> #1  0x080487ac in add (hashtable=0x804b008, 
>     number=0x804b740 "9900101001", name=0x804b730 "Smithpolow",
> time=6943) 
>         new_elem = 0xffffffff
>         hashval = 27
> #2  0x08048b25 in main (argc=1, argv=0xbffff4b4) 
>         number = 0x804b740 "9900101001"
>         name = 0x804b730 "Smithpolow"
>         time = 6943
>         i = 2
代码:


实际上,您没有显示
add()
的源代码,它可能会调用
lookup\u on_Clients()
,而回溯提到
lookup()
,而不是
lookup\u on_Clients()
,因此我不能确定,但我的诊断是:

  • 回溯显示
    list=0xffffffff
    ——这绝对不是一个有效地址,因此可能是
    list->name
    访问导致了SIGSEGV
  • 我还为这样一个事实感到困扰,即客户机上
    lookup\u()的
    number
    参数被声明为
    char number[10]
    ,但gdb显示它包含一个10位数字——这表明持有此参数的变量以相同的方式声明,这意味着没有空间终止0字节。事实上,您正在调用
    strcmp()
    ,这意味着您将
    number
    视为以nul结尾的字符串,因此保存参数的变量作为
    number
    (可能是在
    add()
    中声明的局部变量)传递给
    lookup\u on\u Clients()
    应声明为大小至少为11的数组,以避免崩溃。如果
    add()
    直接传递它自己的
    number
    参数,那么您是安全的,因为它是通过
    main()
    中的
    strdup()
    动态分配的,足够大,但是我仍然会更改
    在客户机上查找()的声明

您在
编号中没有空终止符的空间。您将
number
的大小设置为等于10个字符,但数字中有10个数字,并且没有\0的空格

编辑:

我查看了你的更新代码。您创建了初始大小为17的哈希表,但hasval为27。但是您没有适当扩展哈希表大小的代码

new_elem=hashtable[hashval].head;
if(hashtable[hashval].length>0) // <-- when hashval is out of array 
                                // hashtable[hashval] can have any value of length and head (not NULL)
new_elem=hashtable[hashval].head;

如果(hashtable[hashval].length>0)/这里的根本问题是创建一个包含17个bucket的hashtable:

my_hash_table = createHashTable(17);
但是C数组是基于0的,
PrimesIndex
从1开始,而不是0,因此在
add()
中,调用
hash()

将返回一个介于0和28之间的数字,而不是介于0和16之间的数字。因此,在某个时刻,一个超出范围的值将被分配给
hashval
,随后的一个访问将被
hashval
索引,例如

new_elem=hashtable[hashval].head;
将读取未初始化的内存,最终导致疯狂的指针值,如以后出现的
0xffffff

解决方案:更改
int PrimesIndex=1
int PrimesIndex=0

但老实说,我认为我可能还遗漏了其他一些问题。有:

  • 中的
    for
    循环出现问题,而
    main()中的
    循环出现问题,我在评论中已经指出了这一点
    
  • number
    参数对
    lookup\u on_Clients()
    的可疑声明
  • 有时调用函数
    lookup()
    ,有时调用客户机上的
    lookup()
    
  • 我不相信
    my__linetok()
    (您不显示源代码)能正常工作——至少,除非它使用静态缓冲区,否则它必须分配一个
    char*
    数组,以便保存指向各个令牌的指针,而这些令牌永远不会被释放——内存泄漏

我想这不是SEGFULT的原因,但您不想与
列表->数字-/code>,而不是
列表->名称-/code>进行比较吗?此外,回溯意味着您在一个名为
查找()
的函数中,该函数是从一个名为
添加()
的函数调用的。这些在哪里?@FILIaS:这仍然不能解释客户机上的
lookup()
/
lookup()
差异!您确定这是与回溯对应的代码吗?另外,您是否注意到
list=0xffffffff
?@FILIaS:不,但通过步进调试器或添加printf语句来跟踪它为什么会变成这样应该不会太难。我发布了add()函数。您可以检查。虽然您确定原始字符串中的\0没有被其他数据替换,但可以。但通常情况下,这是不可预测的行为。那么,我该怎么做才能做得更好呢?试着
strncmp(number,list->number,10)
只是为了让sure@DReJ. 检查过了。都一样。结果没有变化。当我发布一些新功能时,如果你介意的话,你可以重新查看我的帖子。Thanks@DReJ. 这是正确的。那么我是否应该更改哈希()???:/还是桌子的初始尺寸?没错。PrimesIndex为1的唯一原因是,从一开始我就创建了一个包含17个bucket(primes上的第一个数字)的哈希表,所以我认为从0开始是没有用的。不管怎样,我相信同样的,它;这不是个严重的问题。(编辑:我指的是PrimesIndex,无论如何我都会更改它!)@FILIaS:是的,这就是问题所在。我的解释有什么你不明白的?@j_random_hacker。第一个:我已经改变了,谢谢。第二个注释:可疑的是。但我能做些什么更好呢?第三个注意事项:那是复制粘贴的,不要注意这些。第四个:据我所知,是的,这段代码有漏洞。但我不想改变它,所以…@FILIaS:所以你把它改成了
intprimesindex=0你还是会遇到同样的问题吗?@j_random_hacker。现在我明白了PrimesIndex的意思,我没有注意到我在hash()上使用了它。谢谢
my_hash_table = createHashTable(17);
int hashval=hash (hashtable,number);
new_elem=hashtable[hashval].head;