【问题标题】:hashedmap and pointer to structs: CXX0030: Error: expression cannot be evaluatedhashedmap 和指向结构的指针:CXX0030:错误:无法评估表达式
【发布时间】:2017-12-26 00:16:11
【问题描述】:

我试图在 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];

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

【问题讨论】:

  • 在调试器中单步调试你的程序,看看哪里出错了。
  • “索引”超出哈希表大小,或者您没有初始化哈希表。尽管也可能有不同的原因。运行 valgrind。
  • using namespace std; 在 C 程序中做什么?!
  • `#include 在 C 程序中做了什么?
  • 在调用任何堆分配函数时:(malloc, calloc, realloc) 1) 始终检查 (!=NULL) 返回值以确保操作成功。如果不成功(==NULL)则调用perror()输出封闭的文本和系统认为函数失败的原因stderr 2)返回的类型是void*,可以分配给任何指针。强制转换只会使代码混乱,使其更难以理解、调试等

标签: c pointers debugging visual-studio-2012 hashmap


【解决方案1】:

基本上你对初始化哈希桶的想法是错误的。

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

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

请注意,我使用calloc 而不是malloc 以确保它将初始化到NULL 这些内存区域。所以,基本上这里我们创建了 20 个桶来由哈希表管理。

同样,你不应该这样做for (int i = 0; i &lt; 20; i++),这是错误的。您将在插入时管理存储桶,因此,当您插入不在哈希表中的内容时,您会为该条目分配内存。

您在此处混合使用CC++,请务必在提交问题时说明。

我将在这里粘贴我所做的更改,因为您使用了很多转换来获得正确的指针类型,但如果您使用正确的结构类型,则没有必要。

#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;
}

【讨论】:

  • 谢谢..这是一个非常详细的解释。理解我的错误
  • 表达式:sizeof( char ) 在标准中定义为 1。将任何内容乘以 1 绝对没有效果,只会使代码混乱。建议在对 malloc() 的调用中删除该表达式
  • 请参阅我对 OP 关于调用堆分配函数的问题的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
  • 2014-05-13
  • 1970-01-01
  • 2013-02-15
  • 2023-04-04
  • 2013-01-29
  • 1970-01-01
相关资源
最近更新 更多