Display() 重置整个数组 C++

Display() resets the entire array C++

我尝试创建一个哈希映射,使用分离链接将其输入存储为链表节点。第一个显示函数给出了理想的输出,但下一个将整个数组重置为空 nullptr。我使用了相同的 class object 所以它不应该每次都给出相同的结果吗?是因为析构函数吗?我想这可能是因为我插入了一个新项目所以我删除了它并且同样的事情仍然存在。我唯一怀疑的是 display() 函数,但请指出问题是否来自其他地方。

抱歉 post 太长了,我想确保每个人都能看到完整的代码以发现问题。

#include <iostream>
#include <string>
#include "C:\Users\admin\source\repos\hash-library-master\sha3.cpp"
using namespace std;

const int TABLE_SIZE = 11;

struct HashNode
{
    string key;
    string value;
    HashNode* next;
};

class HashMap {
private:
    HashNode **table;

public:
    //each element of table will be a root pointer to their respective chain
    HashMap() {
        table = new HashNode*[TABLE_SIZE];
        for (int i = 0; i < TABLE_SIZE; i++)
        {
            table[i] = nullptr;
        }   
    }

    //hashing algorithm using SHA3 (courtesy of Stephan Brumme)
    string hashFunc(string input)
    {
        string key;
        SHA3 sha3;

        key = sha3(input);

        return key;
    }

    //insert new node
    void insert(string key, string value)
    {
        //using hashing function to calculate hash index from string variable key
        int hash = 0;
        for (int a = 0; a < key.length(); ++a)
            hash += key[a];
        hash = hash % TABLE_SIZE;

        //create new node to store data
        HashNode* newNode = new HashNode;
        newNode->value = value;
        newNode->key = key;
        newNode->next = nullptr;

        //check and insert new node to front of line
        if (table[hash] == nullptr)
            table[hash] = newNode;
        else
        {
            newNode->next = table[hash]->next;
            table[hash]->next = newNode;
        }
    }

    void display()
    {
        for (int i = 0; i < TABLE_SIZE; ++i)
        {
            if (table[i] == nullptr)
                cout << i << " NULL" << endl;
            else
            {
                while (table[i] != nullptr)
                {
                    cout << i << " " << table[i]->value << "; ";
                    table[i] = table[i]->next;
                    if (table[i] == nullptr)
                        cout << "(end of chain)" << endl;
                }
            }
        }   
    }

    ~HashMap() {
        for (int i = 0; i < TABLE_SIZE; i++)
            if (table[i] != NULL)
                delete table[i];
        delete[] table;
    }
};

Driver

#include <iostream>
#include <string>
#include "hashMap.h"
using namespace std;

int main()
{
    HashMap obj;
    
    //test insert
    obj.insert("5", "3100 Main St, Houston TX ");
    obj.insert("5", "2200 Hayes Rd, Austin TX");
    obj.insert("226", "1775 West Airport St, San Antonio TX");
    obj.insert("273", "3322 Walnut Bend, Houston TX");
    obj.insert("491", "5778 Alabama, Waco TX");
    obj.insert("94", "3333 New St, Paris TX");

    obj.display(); //resolved

    cout << endl << endl;

    //testing new hashing algorithm
    string input, key;
    cout << "Please enter any new address you want to store: ";
    cin >> input;

    key = obj.hashFunc(input); //create hash key
    obj.insert(key, input);
    obj.display(); //resets the array somehow

    return 0;
}

输出

0 1775 West Airport St, San Antonio TX; (end of chain)
1 NULL
2 3322 Walnut Bend, Houston TX; (end of chain)
3 NULL
4 5778 Alabama, Waco TX; (end of chain)
5 NULL
6 NULL
7 NULL
8 NULL
9 3100 Main St, Houston TX ; 9 2200 Hayes Rd, Austin TX; (end of chain)
10 3333 New St, Paris TX; (end of chain)

//where display() resets
Please enter any new address you want to store: ewrewrw
0 NULL
1 ewrewrw; (end of chain)
2 NULL
3 NULL
4 NULL
5 NULL
6 NULL
7 NULL
8 NULL
9 NULL
10 NULL

您的 display 函数通过循环将 table 的所有元素设置为 nullptr,直到它们变为 nullptr

您应该使用另一个指针变量进行迭代以避免这种破坏。

    void display()
    {
        for (int i = 0; i < TABLE_SIZE; ++i)
        {
            if (table[i] == nullptr)
                cout << i << " NULL" << endl;
            else
            {
                HashNode *p = table[i]; // another pointer variable for iterating
                while (p != nullptr)
                {
                    cout << i << " " << p->value << "; ";
                    p = p->next;
                    if (p == nullptr)
                        cout << "(end of chain)" << endl;
                }
            }
        }   
    }

创建所有不应更改对象本身的成员函数const。这样可以确保在 const 上下文中使用对象时可以使用该函数,并且还可以让编译器在您出错时帮助您。如果您尝试修改函数中的对象,它会给您编译错误,因此会抱怨您在当前代码中对对象进行更改的行 table[i] = table[i]->next;

因此,首先创建函数 const 并修复错误。修复到位后,它可能看起来像这样:

void display() const  // const added
{
    for (int i = 0; i < TABLE_SIZE; ++i)
    {
        if (table[i] == nullptr)
            cout << i << " NULL" << endl;
        else
        {
            // using a temporary pointer, ptr, to go through the list
            for(HashNode* ptr = table[i]; ptr != nullptr; ptr = ptr->next)
            {
                cout << i << " " << ptr->value << "; ";
            }
            cout << "(end of chain)" << endl;
        }
    }   
}