代码之家  ›  专栏  ›  技术社区  ›  Shiva Sairam M

哈希映射和指向结构的指针:CXX0030:错误:无法计算表达式

  •  0
  • Shiva Sairam M  · 技术社区  · 7 年前

    我正在尝试用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];
    

    请告诉我为什么代码会崩溃。

    1 回复  |  直到 7 年前
        1
  •  1
  •   campescassiano    7 年前

    基本上,初始化散列桶的想法是错误的。

    main() 函数基本上您只需要为哈希表的存储桶分配内存,所以您只需要:

     hashItem** hashtable = (hashItem**)calloc(20, sizeof(hashItem**));
    

    注意我使用的 calloc 而不是 malloc 确保它将初始化为 NULL 这些内存区域。因此,基本上我们在这里创建了20个bucket,由哈希表管理。

    同样,你不应该这样做 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;
    }