【问题标题】:Singly-Linked List Add Function - Read Access Violation单链表添加功能 - 读取访问冲突
【发布时间】:2016-09-02 00:26:38
【问题描述】:

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

代码的 LinkedList 部分自行运行,但我确信那里也需要进行一些更正。我的主要问题是,当尝试添加到链接列表时,我得到(在 LinkedList.h 的第 64 行):

抛出异常:读取访问冲突。 this->head 是 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;
        }
    }

};

列出Tester.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");
}

【问题讨论】:

  • 建议你尽可能使用标准库容器,在这种情况下使用 std::forward_list 见:en.cppreference.com/w/cpp/container/forward_list
  • 请注意 std::forward_list 是 C++11 中的新内容(我想这段代码正在使用它)。在早期版本中,只有std::list(这是一个双链表)。

标签: c++ linked-list visual-studio-2015


【解决方案1】:

你在不应该的地方复制:

这个:

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);

即使head 是空指针也可以工作。您可能需要相应地调整其他代码。

【讨论】:

    【解决方案2】:

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

    #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;
        }    
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-09
      • 1970-01-01
      • 2017-03-28
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      • 2020-01-04
      • 1970-01-01
      相关资源
      最近更新 更多