Перемещение элементов между двумя хеш-таблицами - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь создать программу, которая вставляет и удаляет элементы из созданной мною хеш-таблицы (хеш-таблица работает нормально).Программа имеет главное меню и будет вызывать функции insert и delete при правильном вводе.

Программа состоит из 2 хеш-таблиц:

  • active_users хеш-таблица
  • inactive_users хеш-таблица

Когда пользователь "удален », он перемещает пользователя из хеш-таблицы активных пользователей в хеш-таблицу неактивных пользователей.

Проблема: Чтобы переместить пользователя из активной хеш-таблицы в неактивную, я сначала получаю информацию о пользователе изактивную хеш-таблицу и вставьте ее в неактивную хеш-таблицу.Затем я удаляю его из активной хеш-таблицы.Однако по какой-то причине он также удаляется из неактивной хеш-таблицы, вызывая ошибку.

Примечание: Функции insert2, delete_item и contains - это все хеш-функции, которыевызывается для выполнения операций внутри хеш-таблицы.Все эти функции работают хорошо, поэтому я не думаю, что проблема связана с реализацией хеш-таблицы.

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 голосов
/ 29 мая 2018

Это несколько наблюдений.Я думаю, что вы должны серьезно изменить свой код.По моему мнению, у вас должна быть только одна функция move_user, которая перемещает пользователя из одной таблицы в другую и устанавливает для занятого сегмента значение null (и, таким образом, убирает флаг occupied из структуры user, чего не происходит.принадлежат там):

В insert2 вы добавляете элемент, даже если он уже есть (вы не проверяете это).

В delete_item вы уменьшаете количество элементов дажеесли элемент не был найден.

В insert2 вы перезаписываете существующий элемент и пропускаете память.

В insert2 вы не проверяете, есть ли элемент введро.Проверка
while (HashTable->buckets[position]->occupied может, таким образом, вызвать ошибку сегмента, если сегмент нулевой.


Относительно проблемы, о которой вы сообщаете: когда вы делаете
user *tmp = get_item(active_users, input_a);, вы получаете указатель наПользователь.Затем вы вставляете эту запись, указанную в неактивной хеш-таблице, и «удаляете» ее из активной хеш-таблицы.Однако ваше «удаление» - это просто установка флага занятости в пользовательской записи на ноль, так что теперь он не будет найден ни в другой хэш-таблице.Как сказано выше, этот флаг не принадлежит структуре данных пользователя.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...