Ha sh таблица - проблема с деструктором (освобожденный указатель не выделен) - PullRequest
0 голосов
/ 13 марта 2020

У меня есть HashTable, где коллизии обрабатываются цепочкой (связанные списки). Первый узел каждого связанного списка имеет указатель с каждой позиции массива. Ниже показан обычный конструктор вместе с правилом 3 функций.

Хотя мой код компилируется, а мои функции (add, remove, et c) выдают правильный вывод, у меня возникла проблема с деструктор (IDE указывает на него потоком 1: сигнал SIGABRT), и консоль отображает «освободившийся указатель не был выделен» после завершения работы моей программы драйвера. Я не могу понять, что пошло не так, поэтому любая помощь будет оценена. Я не включил свой код ни в одну из других функций (add, remove, et c), кроме конструкторов / деструкторов.

Даже когда я закомментирую конструкторы copy и перегружены =, та же проблема все еще возникает с деструктором.

Спецификация:

class HashTable {

public:

    HashTable(int);
    ~HashTable();
    HashTable(const HashTable &);
    HashTable& operator=(const HashTable &);

private:

    struct Node {
        string word;
        int wordCount;
        Node * next;

        // node constructor
        Node(string w, int count) {
            word = w;
            wordCount = count;
            next = nullptr;
        }
    };

    Node** wordList;
    int capacity;

    int hashFunction(string);
};

Реализация больших 4:

конструктор:

HashTable::HashTable(int cap) {
    capacity = cap;
    wordList = new Node*[capacity];
    for (int i = 0; i < capacity; i++)
        wordList[i] = nullptr;   
}

деструктор (там, где проблема кажется)

HashTable::~HashTable() {
    for (int i = 0; i < capacity; i++) {
        Node* curr = wordList[i];
        while (curr != nullptr) {
            Node* prev = curr;
            curr = curr->next;
            delete prev;          
        }
    }
    delete[] wordList;
}

копировать конструктор:

HashTable::HashTable(const HashTable &obj) {
    capacity = obj.capacity;
    wordList = new Node*[capacity];
    for (int i = 0; i < capacity; i++) {
        if (obj.wordList[i] == nullptr)
            continue;
        Node * newNode = new Node(obj.wordList[i]->word,        
                                  obj.wordList[i]->wordCount);
        wordList[i] = newNode;
    }
}

копировать оператор присваивания:

HashTable& HashTable::operator=(const HashTable &obj) {
    if (this != &obj) {
        for (int i = 0; i < capacity; i++) {
            Node* curr = wordList[i];
            while (curr != nullptr) {
                Node* prev = curr;
                curr = curr->next;
                delete prev;
            }
        }
        delete[] this->wordList;

        this->capacity = obj.capacity;
        this->wordList = new Node*[capacity];
        for (int i = 0; i < this->capacity; i++) {
            if (obj.wordList[i] == nullptr)
                continue;                
            Node * newNode = new Node(obj.wordList[i]->word,
                                      obj.wordList[i]->wordCount);
            this->wordList[i] = newNode;
        }
    }
    return *this;
}

1 Ответ

2 голосов
/ 13 марта 2020

В вашем конструкторе копирования и операторе копирования вы копируете указатели списка из obj в this. Это оставляет одинаковые указатели на обоих объектах, что приводит к двойному освобождению и другим проблемам после освобождения одного HashTable,

Когда вы делаете копии, вам нужно сделать Deep Copy , который выделить новые узлы для копии списка слов.

...