展开链接哈希表。代码错误。[已更新-新问题]
使用链表扩展哈希表会出现一些错误和警告。我想确保以下代码是正确的(扩展函数)并找出引发这些警告/错误的原因
编辑:感谢@nos,他注意到我的原型缺少我的警告+错误指消失了。不幸的是现在有这个:“在函数expand':未定义引用
add'collect2:ld返回1退出状态
编辑2:我注意到add函数返回一个列表* 在扩展函数上没有变量可以“获取”它......但错误仍然存在:/
EDIT3:分段错误 :( 使用 gdb 运行:* glibc 检测到 损坏的双链表:0x0804c6b0 ** 已添加新添加函数
编辑:使用 gdb 运行时 strcmp 出现分段错误:
(gdb) bt 已满
0 0x080487b9 查找中(hashtable=0x804b008,hashval=27,
number=0xbffff3f2 "6900101001") at pro.c:80 列表 = 0xffffffff
1 0x0804883b 添加 (hashtable=0x804b008,
number=0xbffff3f2“6900101001”,name=0x804b6e0“Irgaedggfs”,
时间=6943) 在 pro.c:96 新元素 = 0xffffffff 哈希值 = 27
2 0x08048bc1 in main (argc=1, argv=0xbffff4b4) at pro.c:234
<前><代码>数字=“6900101001” 名称= 0x804b6e0“Irgaedggfs” 时间=6943
typedef struct
{
int length;
struct List *head;
} HashTable;
//resolving collisions using linked lists - chaining
typedef struct
{
char *number;
char *name;
int time;
struct List *next;
}List;
HashTable* expand( HashTable* h )
{
HashTable* new;
int n;
List *node,*next;
PrimesIndex++;
int new_size= primes[PrimesIndex]; /* double the size,odd length */
if (!(new=malloc((sizeof( List*))*new_size))) return NULL;
for(n=0; n< h->length; ++n) {
for(node=h[n].head; node; node=next) {
add (new, node->number, node->name,node->time);
next=node->next;
free(node);
}
}
free(h);
return new;
}
int add ( HashTable* hashtable,char number[10],char* name,int time)
{
List *new_elem;
int hashval=hash (hashtable,number);
new_elem=hashtable[hashval].head;
if(hashtable[hashval].length>0)
{
if ((lookup (hashtable,hashval,number))!=NULL) {return 0;}
}
if (!(new_elem=malloc(sizeof(struct List)))){ return -1;}
//insert values for the new elem
new_elem->number=strdup(number);
new_elem->name=strdup(name);
new_elem->time=time;
hashtable[hashval].head=new_elem;
new_elem->next=NULL;
hashtable[hashval].length++;
/* rehash existing entries if necessary */
if( TableSize(hashtable)>= 2*size])
{
hashtable = expand(hashtable);
if (hashtable ==NULL){
return 0;
}
}
return 1;
}
List *lookup ( HashTable *h ,int hashval,char number[10])
{
List *list=h[hashval].head;
for(list; list!=NULL; list=list->next){
if (strcmp(number,list->number)==0) //**SEGMENTATION**!!!!
return list;
}
return NULL;
}
Expanding a hashtable with linked lists there are some errors and warnings. I wanna make sure that the following code is right (expand function) and find out what happens that raise these warnings/errors
EDIT:Thanks to @nos who noticed that my prototype was missing the warnings+errors I refered to gone. Unfortunately now there is this one: " In function expand': undefined reference to
add' collect2: ld returned 1 exit status
EDIT2: I noticed that add function returns back a List* which on expand function there is none variable to "get" it. I put a value there...but error remains :/
EDIT3: Segmentation Fault :( Running with gdb: * glibc detected corrupted double-linked list: 0x0804c6b0 ** CORRECTED. NEW ADD FUNCTION ADDED.
EDIT: Segmentation Fault on strcmp on lookup function. Running with gdb:
(gdb) bt full
0 0x080487b9 in lookup (hashtable=0x804b008, hashval=27,
number=0xbffff3f2 "6900101001") at pro.c:80 list = 0xffffffff
1 0x0804883b in add (hashtable=0x804b008,
number=0xbffff3f2 "6900101001", name=0x804b6e0 "Irgaedggfs",
time=6943)
at pro.c:96
new_elem = 0xffffffff
hashval = 272 0x08048bc1 in main (argc=1, argv=0xbffff4b4) at pro.c:234
number = "6900101001" name = 0x804b6e0 "Irgaedggfs" time = 6943
typedef struct
{
int length;
struct List *head;
} HashTable;
//resolving collisions using linked lists - chaining
typedef struct
{
char *number;
char *name;
int time;
struct List *next;
}List;
HashTable* expand( HashTable* h )
{
HashTable* new;
int n;
List *node,*next;
PrimesIndex++;
int new_size= primes[PrimesIndex]; /* double the size,odd length */
if (!(new=malloc((sizeof( List*))*new_size))) return NULL;
for(n=0; n< h->length; ++n) {
for(node=h[n].head; node; node=next) {
add (new, node->number, node->name,node->time);
next=node->next;
free(node);
}
}
free(h);
return new;
}
int add ( HashTable* hashtable,char number[10],char* name,int time)
{
List *new_elem;
int hashval=hash (hashtable,number);
new_elem=hashtable[hashval].head;
if(hashtable[hashval].length>0)
{
if ((lookup (hashtable,hashval,number))!=NULL) {return 0;}
}
if (!(new_elem=malloc(sizeof(struct List)))){ return -1;}
//insert values for the new elem
new_elem->number=strdup(number);
new_elem->name=strdup(name);
new_elem->time=time;
hashtable[hashval].head=new_elem;
new_elem->next=NULL;
hashtable[hashval].length++;
/* rehash existing entries if necessary */
if( TableSize(hashtable)>= 2*size])
{
hashtable = expand(hashtable);
if (hashtable ==NULL){
return 0;
}
}
return 1;
}
List *lookup ( HashTable *h ,int hashval,char number[10])
{
List *list=h[hashval].head;
for(list; list!=NULL; list=list->next){
if (strcmp(number,list->number)==0) //**SEGMENTATION**!!!!
return list;
}
return NULL;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要在调用函数之前声明它们。否则,除其他外,C 将假设您的
expand
函数返回一个 int。简单地,将一个像这样的 prototype 放在文件的顶部,在结构声明之后,之前你的函数定义。
You need to declare functions before you call them. Otherwise C will, among other things, assume your
expand
function returns an int.Simply, place a prototype like this one at the top of your file, after your struct declarations, before your function definitions.
在定义“expand”之前声明函数“add”,其中使用“add”。
List* add ( HashTable* hashtable,char number[10],char* name,int time);
在此处定义扩展..
在此处定义添加...
declare the function "add" before you define "expand", in which you use "add".
List* add ( HashTable* hashtable,char number[10],char* name,int time);
define expand here..
define add here...
(我不知道如何更改计算机中的行;所以我必须发布一个新答案,而不是遵循您的评论。抱歉)
请尝试:
int add ( HashTable** phashtable,char number[10],char* name ,int time){
}
您可能需要相应地修改“add”和“add”的调用。
我不确定这是否有帮助。至少这是错误之一。
该错误是,如果在 add 调用中扩展 Hashtable,则在 add 调用返回后,变量“hashtable”的值不会更改。
(I don't know how to change lines in the computer; so I have to post an new answer rather than follow your comment. sorry)
Pls try:
int add ( HashTable** phashtable,char number[10],char* name,int time){
}
you may need to modify "add" and the invoke of "add" accordingly.
I'm not sure whether this would help. At least this is one of the bugs.
The bug is that if Hashtable is expanded in an add call, after the add call returns, the value of the variable "hashtable" won't change.