首页 > 解决方案 > 哈希表 - 析构函数问题(未分配被释放的指针)

问题描述

我有一个 HashTable,其中通过链接(链表)处理冲突。每个链表的第一个节点都有一个来自每个数组位置的指针。下面显示的是一个常规构造函数以及 3 个函数的规则。

尽管我的代码正在编译并且我的函数(添加、删除等)正在产生正确的输出,但我遇到了析构函数的问题(IDE 使用线程 1:信号 SIGABRT 指向它)并且控制台显示“指针正在在我的驱动程序完成运行后,未分配释放。我不知道出了什么问题,所以任何帮助将不胜感激。除了构造函数/析构函数之外,我没有包含任何其他函数(添加、删除等)的代码。

即使我注释掉复制和重载=构造函数,同样的问题仍然出现在析构函数中。

规格:

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;
}

标签: c++constructorlinked-listhashtablerule-of-three

解决方案


在您的复制构造函数和复制赋值运算符中,您将列表指针从复制objthis. 这会在两个对象中留下相同的指针,一旦释放一个 HashTable,就会导致双重释放和其他问题,

做副本的时候,需要做一个Deep Copy,也就是为词表的副本分配新的节点。


推荐阅读