哈希 table - 析构函数问题(未分配被释放的指针)
Hash table - issue with destructor (pointer being freed was not allocated)
我有一个 HashTable,其中通过链接(链表)处理冲突。每个链表的第一个节点都有一个来自每个数组位置的指针。下面显示的是一个常规构造函数以及 3 个函数的规则。
尽管我的代码正在编译并且我的函数(添加、删除等)正在生成正确的输出,但我在析构函数方面遇到了问题(IDE 通过线程 1: 信号指向它SIGABRT) 并且在我的驱动程序完成 运行 后控制台显示 "pointer being freed was not allocated"。我不知道出了什么问题,所以任何帮助将不胜感激。除了 constructors/destructors 之外,我没有包含任何其他功能(添加、删除等)的代码。
即使我注释掉 copy 和 overloaded= 构造函数,同样的问题仍然出现在析构函数上。
规格:
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;
}
在您的复制构造函数和复制赋值运算符中,您正在将列表指针从 obj
复制到 this
。这会在两个对象中留下相同的指针,一旦一个 HashTable 被释放,就会导致双重释放和其他问题,
做拷贝的时候,需要做一个Deep Copy,就是为词表的拷贝分配新的节点
我有一个 HashTable,其中通过链接(链表)处理冲突。每个链表的第一个节点都有一个来自每个数组位置的指针。下面显示的是一个常规构造函数以及 3 个函数的规则。
尽管我的代码正在编译并且我的函数(添加、删除等)正在生成正确的输出,但我在析构函数方面遇到了问题(IDE 通过线程 1: 信号指向它SIGABRT) 并且在我的驱动程序完成 运行 后控制台显示 "pointer being freed was not allocated"。我不知道出了什么问题,所以任何帮助将不胜感激。除了 constructors/destructors 之外,我没有包含任何其他功能(添加、删除等)的代码。
即使我注释掉 copy 和 overloaded= 构造函数,同样的问题仍然出现在析构函数上。
规格:
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;
}
在您的复制构造函数和复制赋值运算符中,您正在将列表指针从 obj
复制到 this
。这会在两个对象中留下相同的指针,一旦一个 HashTable 被释放,就会导致双重释放和其他问题,
做拷贝的时候,需要做一个Deep Copy,就是为词表的拷贝分配新的节点