在 HashMap C 中插入泛型值

Insert of generic values in HashMap C

我有一个函数(create)来创建一个 hashmap

我的 hashmap 大于 11 ,但这是一个示例,我正在搜索以尽可能使代码更清晰。

哈希图将在每个节点中包含一对 KEY-VALUE。我的目标是创建一个 通用插入函数 ,我可以在其中从数组中插入 intchar 等。

在我的示例中,我插入了 Int Insert 函数作为参数 Table t(我插入了我之前创建的 int),两个指向我必须插入的值的指针,我必须在 hashmap 和用户传递的 compare 函数中插入值的位置,以便比较两个键和 return 1 如果它们相等。问题是:当我尝试打印 hashmap (print(t)) 时,它在最后一对插入的每个位置 return。

输入 我的 arr[11] 和 arr2[11]

预期输出

key: 1,val: 11
key: 2,val: 10
key: 3,val: 9
key: 4,val: 8
key: 5,val: 7
key: 6,val: 6
key: 7,val: 5
key: 8,val: 4
key: 9,val: 3
key: 10,val: 2
key: 11,val: 1

实际输出

key: 11, val: 1
key: 11, val: 1
key: 11, val: 1
key: 11, val: 1
key: 11, val: 1
key: 11, val: 1
key: 11, val: 1
key: 11, val: 1
key: 11, val: 1
key: 11, val: 1
key: 11, val: 1

main.c

int compare(void *key,void *key2){
    int k = *(int*)key;
    int k2 = *(int*)key2;
    if(k==k2){
        return 1;
    }else return 0;
}

int main(){

 struct table*t = create(11);
 int arr[11]={1,2,3,4,5,6,7,8,9,10,11};
 int arr2[11]={11,10,9,8,7,6,5,4,3,2,1};
    for(int p=0;p<11;p++){
        int i = arr[p];
        int *key= &i;
        int i2 = arr2[p];
        int *value= &i2;
        insert(t,key,value,p, compare);
    }
 print(t);

function.c

struct node{
    void* key;
    void* val;
    struct node *next;
    struct node *prev;
};

struct table{
    int size;
    struct node **list;
};

struct table *create(int size){
    struct table *t = (struct table*)malloc(sizeof(struct table));
    t->size = size;
    t->list = (struct node**)malloc(sizeof(struct node*)*size);
    int i;
    for(i=0;i<size;i++)
        t->list[i] = NULL;
    return t;
}

void insert(struct table *t,void* key,void* val,int pos, int(*comp)(void*, void*)){

    struct node *list = t->list[pos];
    struct node *newNode = (struct node*)malloc(sizeof(struct node));
    struct node *temp = list;
    while(temp){
        if(((*comp)(temp->key, key))==1){
            printf("%s", "key already create.");
            return;
        }
        temp = temp->next;
    }
    newNode->next = t->list[pos];
    newNode->key = key;
    newNode->val = val;
    if(list!=NULL){
        list->prev = newNode;
    }
    t->list[pos] = newNode;
    newNode->prev = NULL;
}

void print(struct table *t){
    for (int i = 0; i < t->size; ++i) {
        struct node *list = t->list[i];
        while(list){
            if(list->key!=NULL) {
                printf("key: %d, val: %d\n",*(int*)list->key, *(int*)list->val);
            }
            list = list->next;
        }
    }
}

问题出在主函数上。

int i = arr[p];
int *key= &i;

您的密钥是指向 i 变量的指针,而不是指向 arr 中的值的指针。

正确的方法:

int * key = &arr[p];

(值同样的问题)

您在这里为所有值和键传递了相同的地址,因此当您到达终点时,最后一个值已复制到所有指针中

int i = arr[p];
int *key= &i;
int i2 = arr2[p];
int *value= &i2;

相反,您可以从如下位置复制字节数。

//newNode->key = key;
newNode->key = malloc(sizeof(int));
memcpy(newNode->key, key,sizeof(int) );
//newNode->val = val;
newNode->val = malloc(sizeof(int));
memcpy(newNode->val, val,sizeof(int) );

注意:一旦完成,您将必须处理 mallocfree 内存的错误检查。