单链表添加函数-读取访问冲突

Singly-Linked List Add Function - Read Access Violation

本文关键字:函数 读取 访问冲突 添加 链表 单链表      更新时间:2023-10-16

我正在尝试使用单独的Node类和LinkedList类创建一个基本的单链列表。我几乎不知道自己在做什么,因为我刚刚开始学习C++,所以任何帮助都将不胜感激。

代码的LinkedList部分是独立运行的,但我相信也需要进行一些更正。我的主要问题是,当试图添加到链表时,我得到(在LinkedList.h的第64行):

引发异常:读取访问冲突。这个->头是nullptr。

我使用的是Microsoft Visual Studio 2015。这是代码:

LinkedList.h(它是内联的):

#pragma once
#include <iostream>
using namespace std;
class Node
{
private:
    Node *next = NULL;
    int data;

public:
    Node(int newData) {
        data = newData;
        next = NULL;
    }
    Node() {
    }
    ~Node() {
        if(next)
            delete(next);
    }
    Node(int newData, Node newNext) {
        data = newData;
        *next = newNext;
    }
    void setNext(Node newNext) {
        *next = newNext;
    }
    Node getNext() {
        return *next;
    }
    int getData() {
        return data;
    }
};

class LinkedList
{
private:
    Node *head;
    int size;
public:
    LinkedList()
    {
        head = NULL;
        size = 0;
    }
    ~LinkedList()
    {
    }
    void add(int numberToAdd)
    {
        head = new Node(numberToAdd, *head);
        ++size;
    }
    int remove()
    {
        if (size == 0) {
            return 0;
        }
        else {
            *head = (*head).getNext();
            --size;
            return 1;
        }
    }
    int remove(int numberToRemove)
    {
        if (size == 0)
            return 0;
        Node *currentNode = head;
        for (int i = 0; i < size; i++) {
            if ((*currentNode).getData() == numberToRemove) {
                *currentNode = (*currentNode).getNext();
                return 1;
            }
        }
    }
    void print()
    {
        if (size == 0) {
            return;
        }
        else {
            Node currentNode = *head;
            for (int i = 0; i < size; i++) {
                cout << currentNode.getData();
                currentNode = currentNode.getNext();
            }
            cout << endl;
        }
    }
};

列表测试程序.cpp

    // List Tester.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "LinkedList.h"
using namespace std;
int main()
{
    LinkedList myList;
    myList.add(4);
    system("pause");
}

您在不应该复制的地方进行复制:

此:

Node(int newData, Node newNext) {
    data = newData;
    *next = newNext;
}

应该是:

Node(int newData, Node* newNext) {
    data = newData;
    next = newNext;
}

因为现在这个:

head = new Node(numberToAdd, *head);

变为:

head = new Node(numberToAdd, head);

并且即使CCD_ 1是空指针也将工作。您可能需要相应地调整其他代码。

您的整个实现充满了错误。它应该看起来更像这样:

#pragma once
#include <iostream>
class Node
{
private:
    int data;
    Node *next;
public:
    Node(int newData, Node *newNext = NULL)
        : data(newData), next(newNext)
    {}
    void setNext(Node *newNext) {
        next = newNext;
    }
    Node* getNext() {
        return next;
    }
    int getData() {
        return data;
    }
};
class LinkedList
{
private:
    Node *head;
    int size;
public:
    LinkedList()
        : head(NULL), size(0)
    {
    }
    ~LinkedList()
    {
        Node *currentNode = head;
        while (currentNode)
        {
            Node *nextNode = currentNode->getNext();
            delete currentNode;
            currentNode = nextNode;
        }    
    }
    void add(int numberToAdd)
    {
        head = new Node(numberToAdd, head);
        ++size;
    }
    bool remove()
    {
        Node *currentNode = head;
        if (!currentNode)
            return false;
        head = currentNode->getNext();
        delete currentNode;
        --size;
        return true;
    }
    bool remove(int numberToRemove)
    {
        Node *currentNode = head;
        Node *previousNode = NULL;
        while (currentNode)
        {
            if (currentNode->getData() == numberToRemove)
            {
                if (head == currentNode)
                    head = currentNode->getNext();
                if (previousNode)
                    previousNode->setNext(currentNode->getNext());
                delete currentNode;
                return true;
            }
            previousNode = currentNode;
            currentNode = currentNode->getNext();
        }
        return false;
    }
    void print()
    {
        Node *currentNode = head;
        if (!currentNode) return;
        do
        {
            std::cout << currentNode->getData();
            currentNode = currentNode->getNext();
        }
        while (currentNode);
        std::cout << std::endl;
    }    
};

然后可以使用std::forward_list类来简化(如果您使用的是C++11或更高版本):

#pragma once
#include <iostream>
#include <forward_list>
#include <algorithm>
class LinkedList
{
private:
    std::forward_list<int> list;
public:
    void add(int numberToAdd)
    {
        list.push_front(numberToAdd);
    }
    bool remove()
    {
        if (!list.empty())
        {
            list.pop_front();
            return true;
        }
        return false;
    }
    bool remove(int numberToRemove)
    {
        std::forward_list<int>::iterator iter = list.begin();
        std::forward_list<int>::iterator previous = list.before_begin();
        while (iter != list.end())
        {
            if (*iter == numberToRemove)
            {
                list.erase_after(previous);
                return true;
            }
            ++previous;
            ++iter;
        }
        return false;
    }
    void print()
    {
        if (list.empty()) return;
        std::for_each(list.cbegin(), list.cend(), [](int data){ std::cout << data });
        std::cout << std::endl;
    }    
};