哈希 table 打印出默认值,但是当添加项目时会导致地址边界错误
Hash table prints out default values but when items are added results into Address Boundary Error
尝试创建一个哈希 Table 以名称作为键,它的值作为饮料,当调用 printTable() 而不添加项目时(即注释掉以下代码片段)它打印出添加的图像,没有任何地址边界错误:
h.addItem("Paul", "Locha");
h.addItem("Kim", "Iced Mocha");
h.addItem("Emma", "Strawberry Smoothy");
h.addItem("Annie", "Hot Chocolate");
h.addItem("Sarah", "Passion Tea");
h.addItem("Pepper", "Caramel Mocha");
h.addItem("Mike", "Chai Tea");
h.addItem("Steve", "Apple Cider");
h.addItem("Bill", "Root Bear");
h.addItem("Marie", "Skinny Latte");
具有给定默认值的输出图像
但是当通过解析 csv 或直接调用 addItem() 的 class 成员函数添加项目时,程序会呈现如下错误:
➜ Hash Table ./hashTableWithStruct.o
fish: Job 1, './hashTableWithStruct.o' terminated by signal SIGSEGV (Address boundary error)
错误代码如下:
hashTableWithStruct.cpp
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class Hash
{
private:
static const int tableSize = 10;
struct item
{
string name;
string drink;
item *next;
};
item *hashTable[tableSize];
public:
Hash()
{
for (int i = 0; i < tableSize; i++)
{
hashTable[i] = new item;
hashTable[i]->name = "empty";
hashTable[i]->drink = "empty";
hashTable[i]->next = NULL;
}
}
int hashFunct(string key)
{
int hashed = 0;
for (int i = 0; key[i] != '[=13=]'; i++)
{
hashed += (int)key[i];
}
return (hashed % tableSize); //returns the BUCKET value
}
void addItem(string name, string drink)
{
int BUCKET = hashFunct(name);
//if the value at BUCKET hasn't been written yet,
//override the default empty ones
if (hashTable[BUCKET]->name == "empty")
{
hashTable[BUCKET]->name = name;
hashTable[BUCKET]->drink = drink;
}
//otherwise, make a linked list starting from BUCKET
else
{
item *ptr = hashTable[BUCKET];
item *n = new item;
n->name = name;
n->drink = drink;
n->next = NULL;
//the linked list might contain many nodes,
//hence travel to last node and reassign the last node to be this new item
while (ptr != NULL)
ptr = ptr->next;
ptr->next = n;
}
return;
}
int numOfItemsInBucket(int BUCKET)
{
int count = 0;
if (hashTable[BUCKET]->name == "empty")
return count;
else
{
count++;
item *ptr = hashTable[BUCKET];
while (ptr->next != NULL)
{
count++;
ptr = ptr->next;
}
}
return count;
}
void printTable()
{
int num; //holds number of elements(items) in each bucket
for (int i = 0; i < tableSize; i++)
{
num = numOfItemsInBucket(i);
cout << "-----------------------------\n"
<< "Table[" << i << "]" << endl
<< hashTable[i]->name << endl
<< hashTable[i]->drink << endl
<< "# of items in bucket " << i << " : " << num << endl;
cout << "-----------------------------\n";
}
}
};
int main(int argc, char const *argv[])
{
Hash h;
/* string filename = "datasetForHashTable.csv";
ifstream myCSV(filename.c_str());
if (!myCSV.is_open())
{
cout<<"Failed to open file"<<endl;
return 0;
}
string name, drink;
while (myCSV.peek()!=EOF)
{
getline(myCSV, name, ',');
getline(myCSV, drink, '\n');
h.addItem(name, drink);
}
myCSV.close(); */
h.addItem("Paul", "Locha");
h.addItem("Kim", "Iced Mocha");
h.addItem("Emma", "Strawberry Smoothy");
h.addItem("Annie", "Hot Chocolate");
h.addItem("Sarah", "Passion Tea");
h.addItem("Pepper", "Caramel Mocha");
h.addItem("Mike", "Chai Tea");
h.addItem("Steve", "Apple Cider");
h.addItem("Bill", "Root Bear");
h.addItem("Marie", "Skinny Latte");
h.printTable();
return 0;
}
基本上,无法理解为什么 table 不会打印名称和饮料,因为在没有它的情况下打印 table 时它工作正常。
请帮助,自 2 天以来一直试图解决这个问题。
在此 while 循环之后
while (ptr != NULL)
ptr = ptr->next;
指针ptr
等于nullptr
。所以下一条语句
ptr->next = n;
由于取消引用空指针而调用未定义的行为。
你的意思好像是
while (ptr->next != NULL)
ptr = ptr->next;
ptr->next = n;
尝试创建一个哈希 Table 以名称作为键,它的值作为饮料,当调用 printTable() 而不添加项目时(即注释掉以下代码片段)它打印出添加的图像,没有任何地址边界错误:
h.addItem("Paul", "Locha");
h.addItem("Kim", "Iced Mocha");
h.addItem("Emma", "Strawberry Smoothy");
h.addItem("Annie", "Hot Chocolate");
h.addItem("Sarah", "Passion Tea");
h.addItem("Pepper", "Caramel Mocha");
h.addItem("Mike", "Chai Tea");
h.addItem("Steve", "Apple Cider");
h.addItem("Bill", "Root Bear");
h.addItem("Marie", "Skinny Latte");
具有给定默认值的输出图像
但是当通过解析 csv 或直接调用 addItem() 的 class 成员函数添加项目时,程序会呈现如下错误:
➜ Hash Table ./hashTableWithStruct.o
fish: Job 1, './hashTableWithStruct.o' terminated by signal SIGSEGV (Address boundary error)
错误代码如下:
hashTableWithStruct.cpp
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class Hash
{
private:
static const int tableSize = 10;
struct item
{
string name;
string drink;
item *next;
};
item *hashTable[tableSize];
public:
Hash()
{
for (int i = 0; i < tableSize; i++)
{
hashTable[i] = new item;
hashTable[i]->name = "empty";
hashTable[i]->drink = "empty";
hashTable[i]->next = NULL;
}
}
int hashFunct(string key)
{
int hashed = 0;
for (int i = 0; key[i] != '[=13=]'; i++)
{
hashed += (int)key[i];
}
return (hashed % tableSize); //returns the BUCKET value
}
void addItem(string name, string drink)
{
int BUCKET = hashFunct(name);
//if the value at BUCKET hasn't been written yet,
//override the default empty ones
if (hashTable[BUCKET]->name == "empty")
{
hashTable[BUCKET]->name = name;
hashTable[BUCKET]->drink = drink;
}
//otherwise, make a linked list starting from BUCKET
else
{
item *ptr = hashTable[BUCKET];
item *n = new item;
n->name = name;
n->drink = drink;
n->next = NULL;
//the linked list might contain many nodes,
//hence travel to last node and reassign the last node to be this new item
while (ptr != NULL)
ptr = ptr->next;
ptr->next = n;
}
return;
}
int numOfItemsInBucket(int BUCKET)
{
int count = 0;
if (hashTable[BUCKET]->name == "empty")
return count;
else
{
count++;
item *ptr = hashTable[BUCKET];
while (ptr->next != NULL)
{
count++;
ptr = ptr->next;
}
}
return count;
}
void printTable()
{
int num; //holds number of elements(items) in each bucket
for (int i = 0; i < tableSize; i++)
{
num = numOfItemsInBucket(i);
cout << "-----------------------------\n"
<< "Table[" << i << "]" << endl
<< hashTable[i]->name << endl
<< hashTable[i]->drink << endl
<< "# of items in bucket " << i << " : " << num << endl;
cout << "-----------------------------\n";
}
}
};
int main(int argc, char const *argv[])
{
Hash h;
/* string filename = "datasetForHashTable.csv";
ifstream myCSV(filename.c_str());
if (!myCSV.is_open())
{
cout<<"Failed to open file"<<endl;
return 0;
}
string name, drink;
while (myCSV.peek()!=EOF)
{
getline(myCSV, name, ',');
getline(myCSV, drink, '\n');
h.addItem(name, drink);
}
myCSV.close(); */
h.addItem("Paul", "Locha");
h.addItem("Kim", "Iced Mocha");
h.addItem("Emma", "Strawberry Smoothy");
h.addItem("Annie", "Hot Chocolate");
h.addItem("Sarah", "Passion Tea");
h.addItem("Pepper", "Caramel Mocha");
h.addItem("Mike", "Chai Tea");
h.addItem("Steve", "Apple Cider");
h.addItem("Bill", "Root Bear");
h.addItem("Marie", "Skinny Latte");
h.printTable();
return 0;
}
基本上,无法理解为什么 table 不会打印名称和饮料,因为在没有它的情况下打印 table 时它工作正常。 请帮助,自 2 天以来一直试图解决这个问题。
在此 while 循环之后
while (ptr != NULL)
ptr = ptr->next;
指针ptr
等于nullptr
。所以下一条语句
ptr->next = n;
由于取消引用空指针而调用未定义的行为。
你的意思好像是
while (ptr->next != NULL)
ptr = ptr->next;
ptr->next = n;