我正在尝试将(键,值)对添加到哈希图中,但是在插入后无法访问这些值。
每当发生冲突时,当我沿着每个哈希索引进行迭代时,此哈希表都应处理冲突。然后,在到达该索引的(键,值)对列表的末尾时,将其插入。
本质上,它是一个基本的链表哈希表。
问题是,当我再次尝试访问该值时,我一直遇到分段错误(并且我的showTable()
函数也失败了)。在此测试中,我只是在尝试在每个哈希索引处添加了一些东西之后,尝试访问每个哈希索引处的第一对(键,值)。我做的事情可能很愚蠢,但我看到了。
我尚未评论,但我希望代码能自我解释。重要的一点是InsertKeyValuePair()
,但是我添加了所有内容,因为代码审查也将是有益的。
#include <stdlib.h>
#include <stdio.h>
typedef struct TVal KeyValue;
typedef struct TVal {
char *value;
char *key;
KeyValue *next;
} KeyValue;
typedef KeyValue **HashTable;
int MAX_SIZE = 200;
int HashKey(char *Key, int Max);
void InsertKeyValuePair(char *key, char *value, int Index, HashTable table);
int insert(char *Key, char *value, HashTable table, int size);
void showTable(HashTable table, int size);
int HashKey(char *Key, int Max) {
char c = *Key;
int Hash = 0;
int n = 1;
while (c != 0) {
Hash += n * ((int)c);
c = *(Key + n);
n++;
}
return Hash % MAX_SIZE;
}
void InsertKeyValuePair(char *key, char *value, int Index, HashTable table) {
KeyValue *cursor = *(table + Index);
while (cursor != NULL) {
cursor = cursor->next;
}
cursor = malloc(sizeof(KeyValue));
cursor->value = value;
cursor->key = key;
printf("insert <K,V>(%s,%s) HashIndex = %i\n", cursor->key, cursor->value, Index);
//Trying to access value previously inserted
KeyValue *cursor2 = *(table + Index);
printf("<K,V>(%s,%s)\n", cursor2->key, cursor2->value);
}
int insert(char *Key, char *value, HashTable table, int size) {
int Index = HashKey(Key, MAX_SIZE);
InsertKeyValuePair(Key, value, Index, table);
return size + 1;
}
void showTable(HashTable table, int size) {
int i;
for (i = 0; i < size; i++) {
KeyValue *cursor = *(table + i);
if (cursor == NULL)
continue;
while (cursor != NULL) {
printf("==============");
printf("<K,V>(%s,%s)\n", cursor->key, cursor->value);
cursor = cursor->next;
}
printf("==============");
}
}
int main() {
HashTable HTbl = malloc(sizeof(HashTable) * MAX_SIZE);
int size = 0;
size = insert("yeuydfdan", "wesfg", HTbl, size);
size = insert("ywere", "rdgg", HTbl, size);
size = insert("ye4", "3244", HTbl, size);
//showTable(HTbl, MAX_SIZE);
}
最佳答案
您的代码中存在多个问题:
哈希表未初始化为NULL
,从而在尝试取消对其包含的指针的引用时导致分段错误。用calloc()
分配将解决此问题。
将指针隐藏在typedef后面会造成混淆,并且容易出错。main
中的分配应为HashTable HTbl = calloc(sizeof(*HTbl), MAX_SIZE);
InsertKeyValuePair
中的插入代码不会在哈希表存储桶列表的末尾或开头链接新对。
建议使用unsigned
算术来计算哈希键,以避免溢出问题。
指针符号*(table + Index)
令人困惑。您应该改为使用数组符号table[Index]
。
哈希表的长度(MAX_SIZE
)和哈希表中的条目数(size
)之间似乎有些混淆。适当重命名变量可以提高可读性。最好按地址传递计数并返回成功指示符。
这是更正的版本:
#include <stdlib.h>
#include <stdio.h>
typedef struct TVal KeyValue;
typedef struct TVal {
const char *value;
const char *key;
KeyValue *next;
} KeyValue;
typedef KeyValue **HashTable;
static unsigned int HASH_SIZE = 200;
static unsigned int HashKey(const char *key);
static KeyValue *InsertKeyValuePair(const char *key, const char *value, int index, HashTable table);
static int insert(const char *Key, const char *value, HashTable table, int *countp);
static void showTable(HashTable table);
static unsigned int HashKey(const char *key) {
unsigned int hash = 0;
size_t n;
for (n = 0; key[n] != 0; n++) {
hash += n * (unsigned char)key[n];
}
return hash % HASH_SIZE;
}
static KeyValue *InsertKeyValuePair(const char *key, const char *value, int index, HashTable table) {
KeyValue *cursor;
cursor = malloc(sizeof(KeyValue));
if (cursor != NULL) {
KeyValue **cursorp = &table[index];
while (*cursorp != NULL) {
cursorp = &(*cursorp)->next;
}
cursor->value = value;
cursor->key = key;
cursor->next = NULL;
*cursorp = cursor;
}
return cursor;
}
static int insert(const char *key, const char *value, HashTable table, int *countp) {
int index = HashKey(key);
if (InsertKeyValuePair(key, value, index, table)) {
*countp += 1;
return 1;
}
return 0;
}
static void showTable(HashTable table) {
unsigned int i;
for (i = 0; i < HASH_SIZE; i++) {
KeyValue *cursor = table[i];
if (cursor == NULL)
continue;
while (cursor != NULL) {
printf("==============");
printf("<K,V>(%s,%s)\n", cursor->key, cursor->value);
cursor = cursor->next;
}
printf("==============\n");
}
}
int main() {
HashTable HTbl = calloc(sizeof(*HTbl), HASH_SIZE);
int count = 0;
insert("yeuydfdan", "wesfg", HTbl, &count);
insert("ywere", "rdgg", HTbl, &count);
insert("ye4", "3244", HTbl, &count);
showTable(HTbl);
return 0;
}
关于c - 如何在C中正确使用指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57018519/