Display() сбрасывает весь массив C

#c #linked-list #destructor

#c #связанный список #деструктор

Вопрос:

Я попытался создать хэш-карту, хранящую его входные данные в виде узлов связанного списка, используя разделенную цепочку. Первая функция отображения выдает желаемый результат, но следующая сбрасывает весь массив в пустой nullptr . Я использовал один и тот же объект класса, поэтому не должен ли он каждый раз давать один и тот же результат? Было ли это из-за деструктора каким-то образом? Я подумал, что это может быть потому, что я вставил новый элемент, поэтому я удалил его, и то же самое все еще сохраняется. Я подозреваю только функцию display(), но, пожалуйста, укажите, если проблема возникает откуда-то еще.

Извините, если сообщение такое длинное, я хочу убедиться, что каждый может увидеть весь код, чтобы определить проблему.

 #include <iostream>
#include <string>
#include "C:Usersadminsourcereposhash-library-mastersha3.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;
    }
};
 

Драйвер

 #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
 

Комментарии:

1. Что вы наблюдали при пошаговом просмотре вашего кода построчно с помощью отладчика?

Ответ №1:

Создайте все функции-члены, которые не должны изменять сам объект 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;
        }
    }   
}
 

Ответ №2:

Ваша 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;
                }
            }
        }   
    }