在两个哈希表

时间:2018-05-29 14:46:40

标签: c hashtable

我正在尝试制作一个程序,从我制作的哈希表中插入和删除项目(哈希表工作得很好)。该程序有一个主菜单,它将在给定正确输入的情况下调用insertdelete函数。

该程序包含2个哈希表:

  • active_users哈希表
  • inactive_users哈希表

当用户被“删除”时,它会将用户从活动用户哈希表移动到非活动用户哈希表。

问题: 要将用户从活动哈希表移动到非活动状态,我首先从活动哈希表中获取用户信息,然后将其插入非活动哈希表中。然后我从活动哈希表中删除它。但是,由于某种原因,它也会从非活动的哈希表中删除,从而导致错误。

注意:函数insert2delete_itemcontains都是哈希表函数,它们被调用来执行哈希表中的操作。这些函数都运行良好,所以我认为问题不在哈希表的实现上。

typedef struct user{
    char nick[6];
    char name[26];
    bool occupied;
}user; 

void insert_user(hashtable *active_users, hashtable *inactive_users, char *input_a, char *input_b){
    user *new_user = malloc(sizeof(user)); //initializes a new user
    strcpy(new_user->name, input_b);
    strcpy(new_user->nick, input_a);
    new_user->occupied = true;
    if(contains(active_users, input_a) == -1 && contains(inactive_users, input_a) == -1){
        if(load_factor(active_users)){ //checks the size of the hashtable
            resize_HashTable(active_users); // if true, resizes
        }
        insert2(active_users, new_user); //insert user in actives
        printf("+ user %s created\n", input_a);
    }else{
        printf("+ nick %s already used\n", input_a);
    }
}  

void delete_user(hashtable *active_users, hashtable *inactive_users, char *input_a){
    if(contains(active_users, input_a) != -1){
        user *tmp = get_item(active_users, input_a); //get the user from active
        insert2(inactive_users, tmp); //insert in inactives
        delete_item(active_users, input_a); //delete from active
        printf("+ user %s removed\n", input_a);
    }else{
        printf("+ user %s doesnt exist\n", input_a);
    }
}

int main(){
    hashtable *active_users = create();
    hashtable *inactive_users = create();
    char buffer[37];
    char tipo;
    char input_a[6];
    char input_b[26];
    while(fgets(buffer, 37, stdin)){
        sscanf(buffer, "%c %s %[^\n]s", &tipo, input_a, input_b);
        switch(tipo) {
            case 'U' :
                insert_user(active_users, inactive_users, input_a, input_b);
                break;
            case 'R' :
                delete_user(active_users, inactive_users, input_a);
                break;
            default :
                printf("Invalid Operation\n");
        }
    }
    return 0;
}

请求哈希表函数:

void insert2(hashtable *HashTable, user *a){
    int hash_value = hash(a->nick);
    int new_position = hash_value % HashTable->size;
    if (new_position < 0) new_position += HashTable->size;
    int position = new_position;
    while (HashTable->buckets[position]->occupied && position != new_position - 1) {
        position++;
        position %= HashTable->size;
    }
    a->occupied = true;
    HashTable->buckets[position] = a;
    HashTable->elements++;
}

void delete_item(hashtable *HashTable, char *nick){
    int position = contains(HashTable, nick);
    if(position != -1){
        HashTable->buckets[position]->occupied = false;
    }
    HashTable->elements--;
}

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

这些是一些观察。我认为你应该认真重新设计你的代码。在我看来,你应该只有一个函数move_user将用户从一个表移动到另一个表并将其占用的桶设置为null(从而从occupied中删除user标志struct,whch不属于那里):

insert2中你添加一个元素,即使它已经存在(你也没有检查)。

delete_item中,即使找不到元素,也会减少元素的数量。

insert2中,您会覆盖现有项目,从而导致内存泄漏。

insert2中,您不会检查存储桶中是否有元素。因此,如果存储桶为空,则检查while (HashTable->buckets[position]->occupied可能导致seg错误。

<小时/> 至于您报告的问题:何时执行 user *tmp = get_item(active_users, input_a);你得到一个指向用户的指针。然后,插入指向非活动哈希表中的此记录,并从活动哈希表中“删除”它。但是,“删除”只是将用户记录中的占用标志设置为零,因此现在不会在其他哈希表中找到它。如上所述,该标志不属于用户数据结构。