Неизвестная причина нарушения прав доступа для записи в связанном списке - PullRequest
0 голосов
/ 20 февраля 2020

В недавнем проекте, целью которого является изменение связанного списка с помощью функции меню, я сталкиваюсь с единственной ошибкой, которую я не могу исправить, поскольку строка кода является исключительно важной, и Насколько я могу судить, должен работать как задумано. Я получаю сообщение «Исключено исключение: нарушение прав записи. ЭТО было nullptr». Мой класс узла, кажется, является источником ошибки, с ошибкой, представленной в теле функции setNext.

#include "pch.h"
#include <iostream>
#include <vector>
#include <string>

template<class ItemType>
class Node
{
private:
    ItemType value;
    Node<ItemType>* next;
public:
    Node() {
        next = nullptr;
    }
    Node(const ItemType& val) {
        value = val;
        next = nullptr;
    }
    Node(const ItemType& val, Node<ItemType>* nextVal)
    {
        value = val;
        next = nextVal;
    }
    void setVal(const ItemType& val)
    {
        value = val;
    }
    ItemType getVal() const {
        return value;
    }
    void setNext(Node<ItemType>* nextVal)
    {
        next = nextVal; //Exception thrown here.
    }
    Node<ItemType>* getNext() const
    {
        return next;
    }
};

Между тем, в своем классе связанного списка я сузил строку, которая, кажется, вызывала это исключение , так как код не выходит за его пределы. К счастью, он не включает большинство других классов, но этот конкретный экземпляр c, кажется, реагирует так, как будто узел, который я называю, является нулевым указателем.

template<class ItemType>
class linkChain {
private:
    Node<char>* head;
    int count;
    //Node<ItemType>* getPointerTo(const ItemType& target) const;
public:
    linkChain() {
        head = nullptr;
        count = 0;
    }
    linkChain(std::string phrase) : head(nullptr) {
        count = phrase.length();
        for (int i = count - 1; i >= 0; i--) {
            if (head == nullptr) {
                head = new Node<char>();
                head->setVal(phrase[i]);

            }
            else {
                Node<ItemType>* newNode = new Node<char>(phrase[i]);
                newNode->setNext(head);
                head = newNode;
            }
        }
    }
    void append(const linkChain& chain) {
        count += chain.length();
        Node<char>* newNode = head;
        while (newNode != nullptr) {

            newNode = newNode->getNext();
        }
        Node<char>* nextChain = chain.head;
        while (nextChain != nullptr) {
            char nextValu = nextChain->getVal();
            std::cout << nextValu;
            //May be nextVal
            Node<char>* tempNode = new Node<char>(nextValu);

            //THE LINE BELOW THIS
            newNode->setNext(tempNode);
            //THE LINE ABOVE THIS

            nextChain = nextChain->getNext();
            newNode = newNode->getNext();

        }
        newNode = newNode->getNext();
    }

};

А вот код, используемый в основном функция для вызова этого, где charVal является linkChain.

std::cout << "Please enter a string value to test: ";
            std::cin >> testing;
            linkChain<char> addThis = linkChain<char>(testing);
            std::cout << "Is the string inside: " << charVal->submatch(addThis) << "\n";

Я не самый сильный с узлами, поэтому любой совет был бы очень благодарен за то, как я могу исправить эту ошибку, о которой я ничего не понимаю. Другие онлайн-ответы дали либо расплывчатые, либо несвязанные ответы на эту проблему, поэтому они оказали мне небольшую помощь.

1 Ответ

3 голосов
/ 20 февраля 2020

Следующая while l oop - это одна определенная проблема (без полного MCVE, как требуется в комментариях, я не могу правильно проверить другие ошибки):

    while (newNode != nullptr) {
        newNode = newNode->getNext();
    }

Когда это l oop закончится, тогда newNode будет быть nullptr! Но затем, в следующем l oop, несколькими строками позже, вы разыменовываете значение nullptr:

while (nextChain != nullptr) {
    //...
    //THE LINE BELOW THIS
    newNode->setNext(tempNode);
    //THE LINE ABOVE THIS
    //...

Что вы должны делать в первом while l oop, проверяет указатель next:

    while (newNode>getNext() != nullptr) {
        newNode = newNode->getNext();
    }

этот l oop завершится, когда вы указываете на последний узел в списке.

...