#arrays #c #pointers #generics #hashmap
#массивы #c #указатели #общие #hashmap
Вопрос:
У меня есть функция( create
) для создания hashmap.
Моя hashmap больше 11, но это пример, и я ищу, чтобы сделать код более понятным, насколько это возможно.
Хэш-карта будет содержать пару КЛЮЧ-ЗНАЧЕНИЕ в каждом узле. Моя цель — создать общую функцию вставки, в которую я могу вставлять int
и char
т. Д. Из массива.
В моем примере Insert
функция insert Int принимает в качестве параметров Table t
(куда я вставляю int
то, что я создал ранее) два указателя на значения, которые я должен вставить, позицию, в которую я должен вставить значения в hashmap, и compare
функцию, переданную пользователем, чтобы сравнить два ключа и вернуть 1, если они равны. Проблема в том, что когда я пытаюсь распечатать hashmap ( print(t)
), он возвращает в каждой позиции последнюю вставленную пару.
введите мои 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= amp;i;
int i2 = arr2[p];
int *value= amp;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: %dn",*(int*)list->key, *(int*)list->val);
}
list = list->next;
}
}
}
Ответ №1:
вы передаете один и тот же адрес для всех значений и ключа здесь, поэтому к тому времени, когда вы дойдете до конца, последнее значение реплицируется во всех указателях
int i = arr[p];
int *key= amp;i;
int i2 = arr2[p];
int *value= amp;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
памяти.
Ответ №2:
проблема возникла из функции main.
int i = arr[p];
int *key= amp;i;
Ваш ключ является указателем на переменную i, а не на значение в arr.
Правильный путь:
int * key = amp;arr[p];
(та же проблема для значения)