使用 return 代码 -11 (SIGSEGV) 创建 LinkedList 退出

Creating LinkedList exits with return code -11 (SIGSEGV)

所以我正在尝试创建一个链接列表 class 以更好地理解指针和数据结构的工作原理,但我将 运行 保留为 -11 SIGSEGV 错误。当我查找错误时,它说我可能正在使用解除引用的指针或访问超出其范围的数组,但这些对我的程序都没有意义。我到处搜索类似问题,但其中 none 似乎适用于我的程序。其他人能看出我做错了什么吗?

#include <stdexcept>
#pragma once
using namespace std;

#define NODE typename LinkedList<T>::Node*

template <typename T>
class LinkedList {
public:
    void AddHead(const T& data); //Adds new node to the beginning of the list
    void AddTail(const T& data); //Adds new node to the end of the list
    LinkedList(); //Default constructor
    LinkedList(const LinkedList<T>& list); //Copy constructor

    struct Node {
        /*Individual node that stores the data*/
        T data;
        Node* prev;
        Node* next;
        Node(); //Default constructor for node
        Node(T _data); //Data constructor for node
        Node(T _data, Node* _prev, Node* _next); //Full constructor for node
    };
private:
    NODE head = nullptr;
    NODE tail = nullptr;
    unsigned int count;

};

/*Function definitions*/

template <typename T>
void LinkedList<T>::AddHead(const T& data) {
    NODE tempRef = new Node(data, nullptr, head);
    head->prev = tempRef;
    head = tempRef;
    delete tempRef;
    count++;
}

template <typename T>
void LinkedList<T>::AddTail(const T& data) {
    NODE tempRef = new Node(data, tail, nullptr);
    tail->next = tempRef;
    tail = tempRef;
    delete tempRef;
    count++;
}

template <typename T>
LinkedList<T>::LinkedList() {
    count = 0;
    head = nullptr;
    tail = nullptr;
}

template <typename T>
LinkedList<T>::LinkedList(const LinkedList<T>& list) {
    this->head = list.head;
    this->tail = list.tail;
    this->count = list.count;
}

/*Node Constructors*/

template <typename T>
LinkedList<T>::Node::Node() {
    next = nullptr;
    prev = nullptr;
}

template <typename T>
LinkedList<T>::Node::Node(T _data) {
    next = nullptr;
    prev = nullptr;
    data = _data;
}

template <typename T>
LinkedList<T>::Node::Node(T _data, Node* _prev, Node* _next) {
    next = _next;
    prev = _prev;
    data = _data;
}

delete 您在 AddTailAddHead 中添加到列表的节点。这会在列表中留下指向垃圾的指针。

另外,不清楚如何使用你的链表。如果 headnullptr,则不能调用 AddHead(因为 AddHead 取消引用 head),如果 tail 是,则不能调用 AddTail nullptr。由于您的构造函数将 headtail 都设置为 nullptr,接下来您可以做什么?

如果 headnullptr 是合法的,为什么 AddHeadhead->prev = tempRef; 而不检查 head 是否是 nullptr

我强烈建议您记录您的代码。例如,调用 AddHead 所需的前提条件是什么?如果 headnullptr 是否应该是安全的调用或者它不是一个要求?为什么没有记录?

AddHeadAddTail这两个函数都有一个严重的错误,因为分配的节点被立即删除

head = tempRef;
delete tempRef;

tail = tempRef;
delete tempRef;

因此指针 head 和 tail 具有无效值。

此外,函数不会在每个函数中相应地更新 tailhead

最初两个指针都等于nullptr。所以这些陈述

head->prev = tempRef;

tail->next = tempRef;

导致未定义的行为。

函数AddHead可以这样定义

template <typename T>
void LinkedList<T>::AddHead(const T& data) {
    NODE tempRef = new Node(data, nullptr, head);

    if ( head == nullptr )
    {
        head = tail = tempRef;
    }
    else
    {
        head = head->prev = tempRef;
    }

    count++;
}

函数 AddTail 可以看起来像

template <typename T>
void LinkedList<T>::AddTail(const T& data) {
    NODE tempRef = new Node(data, tail, nullptr);

    if ( tail == nullptr )
    {
        tail = head = tempRef;
    }
    else
    {
        tail = tail->next = tempRef;
    }

    count++;
}

复制构造函数(和复制赋值运算符)要么被定义为已删除,要么对作为参数传递的列表进行深度复制。

否则两个列表将尝试删除相同的节点两次(在被你遗忘的析构函数中)。

结构 Node 应声明为私有 class 成员。