C 哈希表-分段错误
不知道为什么我会在这里出现分割错误。我正在尝试创建一个哈希表,它会有冲突,并且数据应该是字符串。所以我使用了一个字符数组作为数据。 最后需要检测碰撞C 哈希表-分段错误,c,hashtable,C,Hashtable,不知道为什么我会在这里出现分割错误。我正在尝试创建一个哈希表,它会有冲突,并且数据应该是字符串。所以我使用了一个字符数组作为数据。 最后需要检测碰撞 #define SIZE 20 struct DataItem { char data[50]; int key; }; struct DataItem* hashArray[SIZE]; struct DataItem* dummyItem; struct DataItem* item; int hashCode(in
#define SIZE 20
struct DataItem
{
char data[50];
int key;
};
struct DataItem* hashArray[SIZE];
struct DataItem* dummyItem;
struct DataItem* item;
int hashCode(int key)
{
return key % SIZE;
}
void insert(int key, char data[50])
{
struct DataItem *item = (struct DataItem*) malloc(sizeof(struct DataItem));
strcpy(item->data, data);
item->key = key;
//get the hash
int hashIndex = hashCode(key);
//move in array until an empty or deleted cell
while (hashArray[hashIndex] != NULL && hashArray[hashIndex]->key != -1)
{
//go to next cell
++hashIndex;
//wrap around the table
hashIndex %= SIZE;
}
hashArray[hashIndex] = item;
}
struct DataItem* delete(struct DataItem* item)
{
int key = item->key;
//get the hash
int hashIndex = hashCode(key);
//move in array until an empty
while (hashArray[hashIndex] != NULL)
{
if (hashArray[hashIndex]->key == key)
{
struct DataItem* temp = hashArray[hashIndex];
//assign a dummy item at deleted position
hashArray[hashIndex] = dummyItem;
return temp;
}
//go to next cell
++hashIndex;
//wrap around the table
hashIndex %= SIZE;
}
return NULL;
}
int detect_collisions()
{
int i = 0;
int collision = 0;
for (i = 0; i < SIZE; i++)
{
if (hashArray[i] != NULL)
{
if (hashArray[i]->key == hashArray[i + 1]->key)
;
collision++;
}
}
return collision;
}
void display()
{
int i = 0;
for (i = 0; i < SIZE; i++)
{
if (hashArray[i] != NULL)
{
printf("Phli dafa: %d\n", i);
printf(" (%d,%s)", hashArray[i]->key, hashArray[i]->data);
}
else
printf(" ~~ ");
}
printf("\n");
}
int main()
{
dummyItem = (struct DataItem*) malloc(sizeof(struct DataItem));
strcpy(dummyItem->data, NULL);
dummyItem->key = -1;
insert(1, "check");
display();
delete(item);
}
您在这里遇到了一个问题:
strcpy(dummyItem->data,NULL);
as strcpy将取消对空指针的引用
要输入空字符串,请使用:
strcpy(dummyItem->data, "");
你的第二个问题是:
delete(item);
此时项为空。因此,这里:
struct DataItem* delete(struct DataItem* item)
{
int key = item->key;
^^^^^^
取消对空指针的引用
也许您的删除功能应该是:
struct DataItem* delete(int key)
{
第三个问题是这里实际上有三个问题:
for (i = 0; i < SIZE; i++)
{
if (hashArray[i] != NULL)
{
if (hashArray[i]->key == hashArray[i + 1]->key)
^^^^^^^^^^^^^^^^
a) May be NULL
b) Out of range when i == size-1
;
^^^
c) Delete this
collision++;
}
}
我猜你想要:
for (i = 0; i < SIZE-1; i++) // Notice
{
if (hashArray[i] != NULL && hashArray[i + 1] != NULL) // Notice
{
if (hashArray[i]->key == hashArray[i + 1]->key)
{
collision++;
}
}
}
您在这里遇到了一个问题:
strcpy(dummyItem->data,NULL);
as strcpy将取消对空指针的引用
要输入空字符串,请使用:
strcpy(dummyItem->data, "");
你的第二个问题是:
delete(item);
此时项为空。因此,这里:
struct DataItem* delete(struct DataItem* item)
{
int key = item->key;
^^^^^^
取消对空指针的引用
也许您的删除功能应该是:
struct DataItem* delete(int key)
{
第三个问题是这里实际上有三个问题:
for (i = 0; i < SIZE; i++)
{
if (hashArray[i] != NULL)
{
if (hashArray[i]->key == hashArray[i + 1]->key)
^^^^^^^^^^^^^^^^
a) May be NULL
b) Out of range when i == size-1
;
^^^
c) Delete this
collision++;
}
}
我猜你想要:
for (i = 0; i < SIZE-1; i++) // Notice
{
if (hashArray[i] != NULL && hashArray[i + 1] != NULL) // Notice
{
if (hashArray[i]->key == hashArray[i + 1]->key)
{
collision++;
}
}
}
问题是
strcpy(dummyItem->data, NULL);
它将尝试复制由NULL指向的字符串,该字符串不指向字符串。。到您的阵列。所以它调用
我想你想要的是
memset(dummyItem->data, 0x00, sizeof(dummyItem->data));
或
或
还要注意,您必须始终检查malloc返回值:它可能无法返回NULL
你也有一个;刚过
if (hashArray[i]->key == hashArray[i + 1]->key)
移除它
我所能看到的最后一件事
delete(item);
是UB,因为项未初始化,因为insert函数中的代码使用了局部变量,可能需要更改
struct DataItem *item = (struct DataItem*) malloc(sizeof(struct DataItem));
到
编辑1
您还可以使用访问超出范围的数组
if (hashArray[i]->key == hashArray[i + 1]->key)
当i=SIZE-1时,哈希数组[i+1]超出范围
此外,hashArray[i+1]可以为空或未初始化。问题在于
strcpy(dummyItem->data, NULL);
它将尝试复制由NULL指向的字符串,该字符串不指向字符串。。到您的阵列。所以它调用
我想你想要的是
memset(dummyItem->data, 0x00, sizeof(dummyItem->data));
或
或
还要注意,您必须始终检查malloc返回值:它可能无法返回NULL
你也有一个;刚过
if (hashArray[i]->key == hashArray[i + 1]->key)
移除它
我所能看到的最后一件事
delete(item);
是UB,因为项未初始化,因为insert函数中的代码使用了局部变量,可能需要更改
struct DataItem *item = (struct DataItem*) malloc(sizeof(struct DataItem));
到
编辑1
您还可以使用访问超出范围的数组
if (hashArray[i]->key == hashArray[i + 1]->key)
当i=SIZE-1时,哈希数组[i+1]超出范围
此外,hashArray[i+1]可以为空或未初始化。如果您在编译代码时启用了调试,使用gcc启用ie-g选项,然后在调试器中运行它,它将告诉您发生seg故障的行。我可以看到有两个地方导致了seg错误——strcpy被传递了NULL,还有对deleteitem的调用,其中item仍然为NULL。大概是因为您认为您使用的是insert中定义的代码,而不是全局定义的代码。如果您在编译代码时启用了带有gcc的ie-g选项,然后在调试器中运行它,它将告诉您发生seg故障的代码行。我可以看到有两个地方导致了seg错误——strcpy被传递了NULL,还有对deleteitem的调用,其中item仍然为NULL。大概是因为您认为您使用的是insert中定义的,而不是全局定义的。strcpydummyItem->data,NULL;--->嘘!或者更好的歌舞厅!strcpydummyItem->数据,NULL;----->嘘!或者更好的歌舞厅!这修复了问题的一部分,但我仍然有一个分段错误。我认为我的显示函数有问题…或者struct DataItem*item=struct DataItem*mallocsizeofstruct DataItem;->item=mallocsizeofstruct数据项;这个问题已经解决了。我在寻找碰撞时又遇到了一个分割错误。int detect_collisions{int i=0;int collision=0;int prev=0;fori=0;ikey;ifhashArray[i]!=NULL prev=hashArray[i]->key;ifhashArray[i]->key==prev collision++;}返回冲突;}这修复了问题的一部分,但我仍然有一个分段错误。我认为我的显示函数有问题…或者struct DataItem*item=struct DataItem*mallocsizeofstruct DataItem;->item=mallocsizeofstruct数据项;这个问题已经解决了。我在寻找碰撞时又遇到了一个分割错误。int detect_collisions{int i=0;int collision=0;int prev=0;fori=0;ikey;ifhashArray[i]!=NULL prev=hashArray[i]->key;ifhashArray[i]->key==prev collision++;}返回冲突;}这修复了问题的一部分,但我仍然有一个分段错误。我认为我的显示功能有问题,这是问题的一个固定部分,但我仍然得到了一个分割错误。我想我的显示功能有问题