C++ 空动态列表

C++ 空动态列表,c++,C++,我已经创建了一个简单的动态模板列表,在清除整个列表时遇到了一些问题 List.h #ifndef LIST_H #define LIST_H #include <Node.h> template <class T> class List { public: typedef Node<T> node_type; typedef node_type* node_pointer; typedef T data_type; type

我已经创建了一个简单的动态模板列表,在清除整个列表时遇到了一些问题

List.h

#ifndef LIST_H
#define LIST_H

#include <Node.h>

template <class T> class List
{
public:
    typedef Node<T> node_type;
    typedef node_type* node_pointer;
    typedef T data_type;
    typedef T& reference_type;

    List();
    void push_back(data_type);
    reference_type at(int);
    void clear();
    void swap(int,int);
    int size();

private:
    int list_size = 0;
    node_pointer head, tail;
};

template <class T> List<T>::List()
{
    head=NULL;
    tail=NULL;
}

template <class T> void List<T>::push_back(data_type data)
{
    if(head == NULL) {
        head = new node_type(data);
        tail = head;
    } else {
        node_pointer temp = new node_type(data);
        temp->setNextNull();
        tail->setNext(temp);
        tail = tail->getNext();
    }
    list_size++;
}

template <class T> typename List<T>::reference_type List<T>::at(int x)
{
    node_pointer pointer=head;
    for(int i=0; i<x; i++)
        pointer=pointer->getNext();

    return pointer->getData();
}

template <class T> void List<T>::clear()
{
    node_pointer pointer = head;
    for(int i=0; i<list_size; i++) {
        node_pointer temp = pointer;
        pointer=pointer->getNext();
        delete(temp);
    }
    head=NULL;
    list_size=0;
}



template <class T> void List<T>::swap(int x, int y)
{
    data_type buffer=at(x);
    at(x)=at(y);
    at(y)=buffer;
}

template <class T> int List<T>::size()
{
    return list_size;
}

#endif // LIST_H
template <class T> class Node
{
public:
    typedef T data_type;
    typedef T& reference_type;

    Node(data_type _data);
    void setData(data_type);
    void setNextNull();
    void setNext(Node*);

    reference_type getData();
    Node* getNext();

private:
    data_type data;
    Node* next;
};


template <class T> Node<T>::Node(data_type _data) : data(_data)
{
    setNextNull();
}

template <class T> void Node<T>::setData(data_type _data)
{
    data=_data;
}

template <class T> void Node<T>::setNextNull()
{
    next=NULL;
}

template <class T> void Node<T>::setNext(Node* _next)
{
    next=_next;
}

template <class T> typename Node<T>::reference_type Node<T>::getData()
{
    return data;
}

template <class T> typename Node<T>::Node* Node<T>::getNext()
{
    return next;
}
\ifndef列表
#定义列表
#包括
模板类列表
{
公众:
类型定义节点节点类型;
typedef node_type*node_指针;
typedef T数据类型;
类型定义T和参考类型;
List();
无效推回(数据类型);
参考类型at(int);
无效清除();
无效掉期(int,int);
int size();
私人:
int list_size=0;
节点\指针头、尾;
};
模板列表::列表()
{
head=NULL;
tail=NULL;
}
模板无效列表::推回(数据类型数据)
{
if(head==NULL){
head=新节点类型(数据);
尾=头;
}否则{
节点指针温度=新节点类型(数据);
temp->setNextNull();
尾部->设置下一步(温度);
tail=tail->getNext();
}
列表_size++;
}
模板类型列表::引用类型列表::at(int x)
{
节点\指针=头;
对于(int i=0;igetNext();
返回指针->获取数据();
}
模板无效列表::清除()
{
节点\指针=头;
对于(int i=0;igetNext();
删除(临时);
}
head=NULL;
列表大小=0;
}
模板无效列表::交换(整数x,整数y)
{
数据类型缓冲区=at(x);
at(x)=at(y);
at(y)=缓冲器;
}
模板int List::size()
{
返回列表的大小;
}
#endif//LIST_H
Node.h

#ifndef LIST_H
#define LIST_H

#include <Node.h>

template <class T> class List
{
public:
    typedef Node<T> node_type;
    typedef node_type* node_pointer;
    typedef T data_type;
    typedef T& reference_type;

    List();
    void push_back(data_type);
    reference_type at(int);
    void clear();
    void swap(int,int);
    int size();

private:
    int list_size = 0;
    node_pointer head, tail;
};

template <class T> List<T>::List()
{
    head=NULL;
    tail=NULL;
}

template <class T> void List<T>::push_back(data_type data)
{
    if(head == NULL) {
        head = new node_type(data);
        tail = head;
    } else {
        node_pointer temp = new node_type(data);
        temp->setNextNull();
        tail->setNext(temp);
        tail = tail->getNext();
    }
    list_size++;
}

template <class T> typename List<T>::reference_type List<T>::at(int x)
{
    node_pointer pointer=head;
    for(int i=0; i<x; i++)
        pointer=pointer->getNext();

    return pointer->getData();
}

template <class T> void List<T>::clear()
{
    node_pointer pointer = head;
    for(int i=0; i<list_size; i++) {
        node_pointer temp = pointer;
        pointer=pointer->getNext();
        delete(temp);
    }
    head=NULL;
    list_size=0;
}



template <class T> void List<T>::swap(int x, int y)
{
    data_type buffer=at(x);
    at(x)=at(y);
    at(y)=buffer;
}

template <class T> int List<T>::size()
{
    return list_size;
}

#endif // LIST_H
template <class T> class Node
{
public:
    typedef T data_type;
    typedef T& reference_type;

    Node(data_type _data);
    void setData(data_type);
    void setNextNull();
    void setNext(Node*);

    reference_type getData();
    Node* getNext();

private:
    data_type data;
    Node* next;
};


template <class T> Node<T>::Node(data_type _data) : data(_data)
{
    setNextNull();
}

template <class T> void Node<T>::setData(data_type _data)
{
    data=_data;
}

template <class T> void Node<T>::setNextNull()
{
    next=NULL;
}

template <class T> void Node<T>::setNext(Node* _next)
{
    next=_next;
}

template <class T> typename Node<T>::reference_type Node<T>::getData()
{
    return data;
}

template <class T> typename Node<T>::Node* Node<T>::getNext()
{
    return next;
}
模板类节点
{
公众:
typedef T数据类型;
类型定义T和参考类型;
节点(数据类型数据);
void setData(数据类型);
void setNextNull();
void setNext(节点*);
引用类型为getData();
节点*getNext();
私人:
数据类型数据;
节点*下一步;
};
模板节点::节点(数据类型数据):数据(\u数据)
{
setNextNull();
}
模板无效节点::setData(数据类型数据)
{
数据=_数据;
}
模板void节点::setNextNull()
{
next=NULL;
}
模板void Node::setNext(Node*\u next)
{
下一步=_下一步;
}
模板typename节点::引用\类型节点::getData()
{
返回数据;
}
模板typename节点::节点*节点::getNext()
{
下一步返回;
}

如果我调用“clear”方法清除列表,几乎所有其他方法都会出现各种错误,但是如果我使用列表下面的版本,则效果会非常好

template <class T> void List<T>::clear()
{
    head=NULL;
    tail=NULL;
    list_size=0;
}
模板无效列表::clear()
{
head=NULL;
tail=NULL;
列表大小=0;
}

只有使用删除功能清除内存时才会出现此问题。如何解决此问题?

您的代码中存在内存泄漏。只需将
head
tail
指向
NULL
即可删除所有列表

执行此操作的最佳方法是创建一个
delete()
函数,然后在整个列表不为空时循环遍历,并逐个节点删除

void deleteHead()
{
    if(head != NULL)
    {
        node *temp = head;
        head = head->next;
        delete temp;
        size--;
    }
}
bool isEmpty()
{
    return head==NULL;
    //return size == 0; <-- this is ok as well.
}
void clear()
{
    while(! isEmpty())
    {
        deleteHead();
    }
    tail = head; //head = NULL
}
void deleteHead()
{
if(head!=NULL)
{
节点*温度=头部;
头部=头部->下一步;
删除临时文件;
大小--;
}
}
布尔是空的
{
返回头==NULL;
//返回大小==0;将
clear()
方法更改为:

template <class T> void List<T>::clear()
{
    node_pointer pointer = head;
    while (pointer != NULL) {
        node_pointer temp = pointer-getNext();
        delete pointer;
        pointer = temp;
    }
    head=NULL;
    tail=NULL;
    list_size=0;
}
模板无效列表::clear()
{
节点\指针=头;
while(指针!=NULL){
node_pointer temp=指针-getNext();
删除指针;
指针=温度;
}
head=NULL;
tail=NULL;
列表大小=0;
}

您的代码非常危险,因为您跳过了重要的检查。请尝试使用
at()
的以下实现:


也就是说,如果你不喜欢这样的问题,你需要到处检查正确性。而且有必要支持返回错误状态以简化错误分析。

“如果我清除调用“清除”方法的列表,我会得到各种错误”。什么错误?如果你发布一个。你不会在
clear
中设置
tail
。我宁愿说她/他在ctor中冗余地将
tail
设置为null。)说真的,在代码中唯一可能导致错误的问题是列表类型本身是可复制和可分配的,当类型包含表示独占所有权的指针时,会产生典型的影响。我要做的另一件事是使事情变得更小、更容易理解,那就是将所有内容都放在一个文件中没有行外定义。然后,我会将节点类设置为嵌套类,在列表类中是私有的,并将其设置为没有任何MemberFunction的简单结构。只有在调用delete时,我才会出现分段错误!我会出现“分段错误”如果我从列表中删除每个节点,但如果我只是将head和tail设置为NULL,则不会!请检查您的插入方法..或者constructor我不明白..我的构造函数几乎为空!您的seg错误是由at(int x)引起的函数。您既不检查
x
也不检查
list\u size>0
很抱歉,我仍然有分段错误!这意味着您正在访问无效内存。您的节点指针可能没有指向有效的节点对象,这意味着您在调用
clear()之前没有正确管理它们
。请提供一个演示如何使用
列表的演示。另外,请阅读(以及C++中的“5条规则”)