哈希 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;