我试图在C中创建一个简单的hashmap.vs在编译时不知道任何错误。但是在执行期间,指向结构的指针变成了一个糟糕的指针。
hashedKey CXX0030: Error: expression cannot be evaluated
以下是代码,任何人都可以告诉我代码崩溃的原因。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
//#include"Header.h"
struct hashItem{
char* hashedKey;
char* hashedValue;
hashItem* next;
};
#define SIZE 20
unsigned long hashf(char *str)
{
unsigned long hash = 5381;
int c;
while (c = *str++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash%SIZE;
}
struct hashItem * createNewItem(char *key, char *value){
struct hashItem *newKeyValue = (struct hashItem *)calloc(1, sizeof(struct
hashItem));
newKeyValue->hashedKey = (char*)malloc(sizeof(char) * 100);
newKeyValue->hashedValue = (char*)malloc(sizeof(char) * 100);
strcpy(newKeyValue->hashedKey, key);
newKeyValue->hashedValue = value;
newKeyValue->next = NULL;
return newKeyValue;
}
void put(struct hashItem** hashTable, char *key, char *value)
{
if (value == NULL)
return;
struct hashItem *newKeyValue = createNewItem(key, value);
int index = hashf(key);
if (hashTable[index] == NULL){
hashTable[index] = newKeyValue;
}
else
{
int inserted = 0;
struct hashItem *p = hashTable[index];
struct hashItem *q = NULL;
while (p != NULL){
int e = strcmp(p->hashedKey, newKeyValue->hashedKey);
if (e == 0){
if (q != NULL)
q->next = newKeyValue;
p->hashedValue = newKeyValue->hashedValue;
inserted = 1;
break;
}
q = p;
p = p->next;
}
if (!inserted)
q->next = newKeyValue;
}
}
struct hashItem * get(struct hashItem** hashTable, char *key){
if (hashTable == NULL)
return NULL;
int index = hashf(key);
if (hashTable[index] != NULL)
{
if (!strcmp(hashTable[index]->hashedKey, key)){
return hashTable[index];
}
else{
struct hashItem *p = hashTable[index];
while (p != NULL){
if (p->hashedKey == key)
return p;
p = p->next;
}
return NULL;
}
}
else{
return NULL;
}
}
int main(){
hashItem** hashtable = (hashItem**)malloc(sizeof(hashItem*)*20);
for (int i = 0; i < 20; i++){
hashtable[i] = (hashItem*)malloc(sizeof(hashItem));
hashtable[i]->hashedKey = NULL;
hashtable[i]->hashedValue = NULL;
hashtable[i]->next = NULL;
}
put(hashtable, "select", "marks");
hashItem* temp = (hashItem*)get(hashtable,"select");
printf("%s", temp->hashedKey);
int k;
scanf("%d", &k);
return 0;
}
在调试期间,代码似乎崩溃在以下几行:
struct hashItem *p = hashTable[index];
请告诉我代码崩溃的原因。
答案 0 :(得分:1)
基本上你认为初始化哈希桶是错误的。
在main()
函数中,基本上你只需要为哈希表的桶分配内存,所以你只需要这个:
hashItem** hashtable = (hashItem**)calloc(20, sizeof(hashItem**));
请注意我使用的是calloc
而不是malloc
,以确保它将初始化为NULL
这些内存区域。所以,基本上我们在这里创建了20个由哈希表管理的桶。
同样,你不应该这样做for (int i = 0; i < 20; i++)
,这是错误的。您将在插入时管理存储桶,因此,当您插入不在哈希表中的内容时,则会为该条目分配内存。
您在这里混合使用C
和C++
,请务必在提交问题时说明。
我将在此处粘贴我所做的更改,因为您使用了大量的转换来获得正确的指针类型,但如果您使用正确的结构类型则没有必要。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct _hashItem{
char* hashedKey;
char* hashedValue;
struct _hashItem* next;
} hashItem;
#define SIZE 20
unsigned long hashf(char *str)
{
unsigned long hash = 5381;
int c;
while (c = *str++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return (hash % SIZE);
}
hashItem * createNewItem(char *key, char *value){
hashItem *newKeyValue = (hashItem *)calloc(1, sizeof(
hashItem));
newKeyValue->hashedKey = (char*)malloc(sizeof(char) * 100);
newKeyValue->hashedValue = (char*)malloc(sizeof(char) * 100);
strcpy(newKeyValue->hashedKey, key);
newKeyValue->hashedValue = value;
newKeyValue->next = NULL;
return newKeyValue;
}
void put(hashItem** hashTable, char *key, char *value)
{
if (value == NULL)
return;
hashItem *newKeyValue = createNewItem(key, value);
int index = hashf(key);
if (hashTable[index] == NULL){
hashTable[index] = newKeyValue;
}
else
{
int inserted = 0;
hashItem *p = hashTable[index];
hashItem *q = NULL;
while (p != NULL){
int e = strcmp(p->hashedKey, newKeyValue->hashedKey);
if (e == 0){
if (q != NULL)
q->next = newKeyValue;
p->hashedValue = newKeyValue->hashedValue;
inserted = 1;
break;
}
q = p;
p = p->next;
}
if (!inserted)
q->next = newKeyValue;
}
}
hashItem * get(hashItem** hashTable, char *kAey){
if (hashTable == NULL)
return NULL;
int index = hashf(key);
if (hashTable[index] != NULL)
{
if (!strcmp(hashTable[index]->hashedKey, key)){
return hashTable[index];
}
else{
hashItem *p = hashTable[index];
while (p != NULL){
if (p->hashedKey == key)
return p;
p = p->next;
}
return NULL;
}
}
else{
return NULL;
}
}
int main(){
hashItem** hashtable = (hashItem**)calloc(20, sizeof(hashItem**));
put(hashtable, "select", "marks");
hashItem* temp = get(hashtable,"select");
printf("%s", temp->hashedKey);
int k;
scanf("%d", &k);
return 0;
}