我目前正在开发一个使用哈希表的程序。我已经在我自己的Hash表类上工作,程序可以运行但在它已经完成涉及哈希表的工作后崩溃了。我得到的错误是访问冲突读取位置错误。我花了几个小时查看我的代码,但仍然无法找到我做错的事情或程序崩溃的原因。以下是我的问题类:
Hashtable.h:
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <string>
#include "LinkedList.h"
#include <iostream>
using namespace std;
class hashTable
{
public:
hashTable();
virtual ~hashTable();
void insertNode(string nodeData);
bool removeNode(string nodeKey);
Node * checkForDuplicate( string nodeData );
private:
LinkedList * tableArray;
int length;
int hash(string stateKey);
};
#endif // HASHTABLE_H
Hashtable.cpp:
#include "hashTable.h"
hashTable::hashTable()
{
length = 181667;
tableArray = new LinkedList[length];
}
int hashTable::hash(string stateKey) {
int multiplier = 1;
int total = 0;
int l = stateKey.length();
for(int i = l - 1; i > -1; --i) {
int temp;
temp = (stateKey[i] - '0') * multiplier;
total += temp;
multiplier = multiplier * 10;
}
return(total) % length;
}
void hashTable::insertNode(string stateData) {
Node * newNode;
newNode = new Node;
newNode->data = stateData;
int index = hash(newNode -> data);
tableArray[index].insertNode(newNode);
delete newNode;
}
bool hashTable::removeNode(string nodeKey) {
int index = hash(nodeKey);
return tableArray[index].removeNode(nodeKey);
}
Node * hashTable::checkForDuplicate( string nodeData )
{
int index = hash( nodeData );
return tableArray[ index ].getNode(nodeData);
}
hashTable::~hashTable()
{
delete [] tableArray;
//dtor
}
LinkedList.h:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<string>
#include<iostream>
using namespace std;
struct Node {
string data;
Node *next;
};
class LinkedList
{
public:
LinkedList();
void insertNode(Node * newNode);
bool removeNode(string stateData);
Node * getNode(string stateData);
int getLength();
virtual ~LinkedList();
private:
Node * top;
int length;
};
#endif // LINKEDLIST_H
LinkedList.cpp:
#include "LinkedList.h"
LinkedList::LinkedList()
{
top = new Node;
top->next = NULL;
length = 0;
}
void LinkedList :: insertNode(Node * newNode) {
Node * a = top;
Node * b = top;
while(b) {
a = b;
b = a -> next;
if (a== NULL) { break; }
}
a -> next = newNode;
newNode -> next = NULL;
length++;
}
bool LinkedList :: removeNode(string stateData) {
if(!top -> next){
return false;
}
Node * a = top;
Node * b = top;
while(b) {
if(b->data == stateData) {
a->next = b->next;
delete b;
length--;
return true;
}
a = b;
b = a ->next;
}
return false;
}
Node * LinkedList :: getNode(string stateData) {
if(top == NULL) { return NULL ;}
Node * current = top;
while (current->next != NULL) {
if((current->data == stateData)) {
return current;
}
current = current -> next;
}
return NULL;
}
int LinkedList :: getLength() {
return length;
}
LinkedList::~LinkedList()
{
Node * a = top;
Node * b = top;
while (b) {
a = b;
b = a->next;
if(b) delete a;
}
}
答案 0 :(得分:2)
您的hashTable::insertNode()
方法正在分配新的Node
对象,然后将其传递给LinkedList::insertNode()
获取对象的所有权,但随后 {之后{1}} ,从而使delete
指向无效内存的悬空指针。对该节点的任何访问都将导致未定义的行为。在LinkedList
取得所有权后,请勿delete
新节点。
如果LinkedList
将LinkedList::insertNode()
作为输入而不是string
指针,那会更好。让Node*
在内部分配新节点。
此外,您的LinkedList
实施通常存在一些其他小问题(例如,不遵循Rule of Three,并且不使用双链表进行更有效的插入和删除)。
尝试更像这样的东西:
Hashtable.h:
LinkedList()
Hashtable.cpp:
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <string>
#include "LinkedList.h"
class hashTable
{
public:
hashTable();
hashTable(const hashTable &src);
~hashTable();
void insertNode(const std::string &nodeData);
bool removeNode(const std::string &nodeData);
bool checkForDuplicate(const std::string &nodeData);
hashTable& operator=(const hashTable &rhs);
private:
std::vector<LinkedList> tableArray;
int length;
int hash(const std::string &nodeData);
};
#endif // HASHTABLE_H
LinkedList.h:
#include "hashTable.h"
hashTable::hashTable()
: length(181667), tableArray(new LinkedList[length])
{
}
hashTable::hashTable(const hashTable &src)
: length(src.length), tableArray(new LinkedList[length])
{
for (int i = 0; i < length; ++i)
tableArray[i] = src.tableArray[i];
}
hashTable::~hashTable()
{
delete[] tableArray;
}
hashTable& hashTable::operator=(const hashTable &rhs)
{
hashTable tmp(rhs);
std::swap(tableArray, tmp.tableArray);
std::swap(length, tmp.length);
return *this;
}
int hashTable::hash(const std::string &nodeData)
{
int multiplier = 1;
int total = 0;
int l = nodeData.length();
for(int i = l - 1; i > -1; --i)
{
int temp = (nodeData[i] - '0') * multiplier;
total += temp;
multiplier *= 10;
}
return total % length;
}
void hashTable::insertNode(const std::string &nodeData)
{
int index = hash(nodeData);
tableArray[index].insertNode(nodeData);
}
bool hashTable::removeNode(const std::string &nodeData)
{
int index = hash(nodeData);
return tableArray[index].removeNode(nodeData);
}
bool hashTable::checkForDuplicate(const std::string &nodeData)
{
int index = hash(nodeData);
return (tableArray[index].getNode(nodeData) != NULL);
}
LinkedList.cpp:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <string>
struct Node
{
std::string data;
Node *previous;
Node *next;
};
class LinkedList
{
public:
LinkedList();
LinkedList(const LinkedList &src);
~LinkedList();
void insertNode(const std::string &nodeData);
bool removeNode(const std::string &nodeData);
Node* getNode(const std::string &nodeData);
int getLength();
LinkedList& operator=(const LinkedList &rhs);
private:
Node *head;
Node *tail;
int length;
};
#endif // LINKEDLIST_H
话虽如此,您可以使用#include "LinkedList.h"
#inclue <algorithm>
LinkedList::LinkedList()
: head(NULL), tail(NULL), length(0)
{
}
LinkedList::LinkedList(const LinkedList &src)
: head(NULL), tail(NULL), length(0)
{
Node *current = src.top;
while (current != NULL)
{
insertNode(current->data);
current = current->next;
}
}
LinkedList::~LinkedList()
{
Node *current = top;
while (current != NULL)
{
Node *next = current->next;
delete current;
current = next;
}
}
LinkedList& LinkedList::operator=(const LinkedList &rhs)
{
LinkedList tmp;
Node *current = rhs.top;
while (current != NULL)
{
tmp.insertNode(current->data);
current = current->next;
}
std::swap(top, tmp.top);
std::swap(bottom, tmp.bottom);
std::swap(length, tmp.length);
return *this;
}
void LinkedList::insertNode(const string &nodeData)
{
Node *newNode = new Node;
newNode->data = nodeData;
newNode->previous = NULL;
newNode->next = NULL;
if (top == NULL) top = newNode;
if (bottom != NULL)
{
newNode->previous = bottom;
bottom->next = newNode;
}
bottom = newNode;
length++;
}
bool LinkedList::removeNode(const string &nodeData)
{
Node* node = getNode(nodeData);
if (node != NULL)
{
if (node->next != NULL)
node->next->previous = node->previous;
if (node->previous != NULL)
node->previous->next = node->next;
if (top == node)
top = node->next;
if (bottom == node)
bottom = node->previous;
delete node;
length--;
return true;
}
return false;
}
Node* LinkedList::getNode(const string &nodeData)
{
Node *current = top;
while (current != NULL)
{
if (current->data == nodeData)
return current;
current = current->next;
}
return NULL;
}
int LinkedList::getLength()
{
return length;
}
完全删除LinkedList
,并使用std::list
简化hashTable
的内存管理:
Hashtable.h:
std::vector
Hashtable.cpp:
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <string>
#include <list>
#include <vector>
class hashTable
{
public:
hashTable();
void insertNode(const std::string &nodeData);
bool removeNode(const std::string &nodeData);
bool checkForDuplicate(const std::string &nodeData);
private:
std::vector< std::list<std::string> > tableArray;
int hash(const std::string &stateKey);
};
#endif // HASHTABLE_H