C++ 正在创建返回代码为-11(SIGSEGV)的LinkedList出口
所以我试图创建一个链表类来更好地理解指针和数据结构是如何工作的,但我一直遇到-11 SIGSEGV错误。当我查找错误时,它说我可能正在使用未引用的指针或访问超出其边界的数组,但这两种情况对我的程序都没有意义。我到处寻找类似的问题,但没有一个适用于我的程序。其他人能看出我做错了什么吗C++ 正在创建返回代码为-11(SIGSEGV)的LinkedList出口,c++,pointers,linked-list,segmentation-fault,doubly-linked-list,C++,Pointers,Linked List,Segmentation Fault,Doubly Linked List,所以我试图创建一个链表类来更好地理解指针和数据结构是如何工作的,但我一直遇到-11 SIGSEGV错误。当我查找错误时,它说我可能正在使用未引用的指针或访问超出其边界的数组,但这两种情况对我的程序都没有意义。我到处寻找类似的问题,但没有一个适用于我的程序。其他人能看出我做错了什么吗 #include <stdexcept> #pragma once using namespace std; #define NODE typename LinkedList<T>::Nod
#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;
}
#包括
#布拉格语一次
使用名称空间std;
#定义节点类型名LinkedList::NODE*
模板
类链接列表{
公众:
void AddHead(const T&data);//将新节点添加到列表的开头
void AddTail(const T&data);//将新节点添加到列表的末尾
LinkedList();//默认构造函数
LinkedList(const LinkedList&list);//复制构造函数
结构节点{
/*存储数据的单个节点*/
T数据;
节点*prev;
节点*下一步;
Node();//节点的默认构造函数
Node(T_data);//节点的数据构造函数
Node(T_data,Node*_prev,Node*_next);//节点的完整构造函数
};
私人:
节点头=nullptr;
节点尾部=nullptr;
无符号整数计数;
};
/*函数定义*/
模板
void LinkedList::AddHead(常量和数据){
节点tempRef=新节点(数据、空PTR、头);
head->prev=tempRef;
head=tempRef;
删除tempRef;
计数++;
}
模板
void LinkedList::AddTail(常量和数据){
节点tempRef=新节点(数据、尾部、空PTR);
tail->next=tempRef;
tail=tempRef;
删除tempRef;
计数++;
}
模板
LinkedList::LinkedList(){
计数=0;
水头=零PTR;
tail=nullptr;
}
模板
LinkedList::LinkedList(常量LinkedList&list){
此->head=list.head;
此->tail=list.tail;
此->计数=list.count;
}
/*节点构造函数*/
模板
LinkedList::Node::Node(){
next=nullptr;
prev=nullptr;
}
模板
LinkedList::Node::Node(T_数据){
next=nullptr;
prev=nullptr;
数据=_数据;
}
模板
LinkedList::Node::Node(T\u数据,Node*\u上一个,Node*\u下一个){
下一步=_下一步;
prev=_prev;
数据=_数据;
}
您可以在AddTail
和AddHead
中删除添加到列表中的节点。这会在列表中留下指向垃圾的指针
此外,还不清楚如何使用链接列表。如果head
是nullptr
(因为AddHead
取消引用head
),则不能调用AddHead
,如果tail
是nullptr
,则不能调用AddTail
。既然您的构造函数将head
和tail
都设置为nullptr
,那么接下来您可以做什么
如果head
成为nullptr
是合法的,为什么AddHead
dohead->prev=tempRef代码>而不检查头
是否为nullptr
我强烈要求您记录代码。例如,调用AddHead
所需的先决条件是什么?如果head
是nullptr
,调用是否应该是安全的?为什么没有记录下来?两个函数AddHead
和AddTail
都有一个严重的错误,因为分配的节点立即被删除
head = tempRef;
delete tempRef;
及
因此,指针head和tail的值无效
此外,各功能中的tail
和head
不会相应更新
最初,两个指针都等于nullptr
。所以这些声明
head->prev = 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++;
}
复制构造函数(和复制赋值运算符)要么应定义为已删除,要么应制作作为参数传递的列表的深度副本
否则,两个列表将尝试删除相同的节点两次(在destructor中)
结构节点
应声明为私有类成员。此head=tempRef;删除tempRef;没有道理。在这些语句之后,head的值无效,因为指向的对象已被删除。不删除tempRef不会导致内存泄漏吗?对不起,如果这是一个愚蠢的问题,我仍然记忆犹新allocation@ManuKolehmainen您已立即删除了它。所以指针有无效的值。我没有想到head等于nullptr会引起问题。来自Java,我认为如果它是nullptr,我可以稍后将其初始化为我需要的任何内容,但显然在C++中并不是那么容易,您可以稍后将其初始化为您想要的任何内容,只是在初始化之前不能取消引用它。
tail->next = tempRef;
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++;
}
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++;
}