在 HashMap C 中插入泛型值
Insert of generic values in HashMap C
我有一个函数(create
)来创建一个 hashmap。
我的 hashmap 大于 11 ,但这是一个示例,我正在搜索以尽可能使代码更清晰。
哈希图将在每个节点中包含一对 KEY-VALUE。我的目标是创建一个 通用插入函数 ,我可以在其中从数组中插入 int
、char
等。
在我的示例中,我插入了 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) );
注意:一旦完成,您将必须处理 malloc
和 free
内存的错误检查。
我有一个函数(create
)来创建一个 hashmap。
我的 hashmap 大于 11 ,但这是一个示例,我正在搜索以尽可能使代码更清晰。
哈希图将在每个节点中包含一对 KEY-VALUE。我的目标是创建一个 通用插入函数 ,我可以在其中从数组中插入 int
、char
等。
在我的示例中,我插入了 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) );
注意:一旦完成,您将必须处理 malloc
和 free
内存的错误检查。