что не так с этой функцией очистки для таблицы ha sh? - PullRequest
0 голосов
/ 24 марта 2020

У меня странная проблема с очисткой всей таблицы ha sh. Ниже приведены структуры данных:

typedef struct data_entry_{
    char data[32];
    struct data_entry_ *next;
}data_entry_t;

typedef struct table_entry_{
    char hash[32];
    struct data_entry_ *next_data;
    struct table_entry_ *next_hash;
}table_entry_t;

typedef struct table_{
    table_entry_t *next;
}table_t;

В основной функции я инициализирую таблицу с помощью функции ниже

table_t *init(){
    table_t *table = calloc(1, sizeof(table_t));
    table_entry_t *node = calloc(1, sizeof(table_entry_t));
    node->next_hash = NULL;
    node->next_data = NULL;
    strcpy(node->hash, "NULL"); 
    table->next = node;
    return table;
}

Добавьте данные в таблицу с помощью функции ниже:

int add(table_t *table, char *data){
    table_entry_t *head = table->next;
    table_entry_t *prev;
    char hash[32];
    hash_function(data, hash);

    if(!strcmp(head->hash, "NULL")){ 
        data_entry_t *item = calloc(1, sizeof(data_entry_t));
        strcpy(item->data, data);
        item->next = NULL;
        strcpy(head->hash, hash);
        head->next_data = item;
        head->next_hash = NULL;
        return 0;
    }
    while(head){
        if(!strcmp(head->hash, hash)){
            data_entry_t *temp = head->next_data;
            data_entry_t *previous;
            while(temp){
                if(!strcmp(temp->data, data)){
                    printf("data exists\n");
                    return 0;
                }
                previous = temp;
                temp = temp->next;
            }
            data_entry_t *item = calloc(1, sizeof(data_entry_t));
            strcpy(item->data, data);
            item->next = NULL;
            previous->next = item;
            return 0;
        }
        prev = head;
        head = head->next_hash;
    }

    table_entry_t *pack = calloc(1, sizeof(table_entry_t));
    data_entry_t *item = calloc(1, sizeof(data_entry_t));
    strcpy(pack->hash, hash);
    strcpy(item->data, data);
    item->next = NULL;
    pack->next_data = item;
    prev->next_hash = pack;
    return 0;
}

И проблема в этой функции:

int flush(table_t *table){
    table_entry_t *head = table->next;
    table_entry_t *temp;
    data_entry_t *current, *previous; 
    if(head->next_data == NULL){
        printf("table is empty\n");
        return -1;
    }
    strcpy(head->hash, "NULL");
    while(head){
        current = head->next_data;
        while(current){
            previous = current;
            current = current->next;
            free(previous);
        }
        temp = head;
        head = head->next_hash;
        free(temp);
    }  
    return 0;
}

после вызова flu sh, когда я хочу показать таблицу, я ожидаю увидеть «таблица пуста», но, очевидно, эта функция не свободна любые узлы. Я очень ценю, если кто-нибудь поможет мне.

1 Ответ

1 голос
/ 24 марта 2020

Вы ожидаете, что освобожденный указатель получит значение NULL.
Это, однако, невозможно, поскольку free() получает только значение внутри указателя, а не адрес, т.е. не указатель на указатель.

Ваш код предполагает, что освобожденный указатель здесь равен NULL:

if(head->next_data == NULL){

Это, однако, будет иметь место только в том случае, если вы записали значение NULL в указатель.

Есть некоторый код что выглядит примерно так: strcpy(head->hash, "NULL");, но я верю, что вы не ожидаете, что в указатель будет записано нестроковое значение NULL.

Вы можете убедиться, что все свободные указатели, которые вы впоследствии освободите, содержат NULL, пишу это сам. Рядом с этим free(previous);. Однако необходимо записать NUL1 в фактический указатель в связанном списке, а не, например, в переменную previous. Вы можете использовать копию указателя, хранящуюся в этой переменной, для освобождения, но не для перезаписи оригинала.

...