空动态列表

时间:2014-06-15 15:17:31

标签: 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;
    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

Node.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;
}

如果我清除了呼叫&#34;清除&#34;方法我在几乎所有其他方法中都会遇到各种错误,但是如果我使用下面的版本,那么列表就可以完美地运行。

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

仅当我使用删除功能清除内存时才会出现此问题。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

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

template <class T> typename List<T>::reference_type List<T>::at(int x)
{
    if (x < 0 || x >= list_size || list_size <= 0)
        return DATA_WITH_ERROR_FLAG; // since you return data instead of pointer,
                                     // you can't return NULL here
                                     // (you need special constant for error status
                                     //  or support it another way)

    node_pointer pointer=head;
    for(int i=0; i<x; i++)
    {
        if (!pointer)
            return DATA_WITH_ERROR_FLAG;
        pointer=pointer->getNext();
    }

    if (!pointer)
        return DATA_WITH_ERROR_FLAG;
    return pointer->getData();
}

之后,您必须在每次at()电话后添加支票。例如,您必须修改swap()以使其安全:

template <class T> void List<T>::swap(int x, int y)
{
    data_type v1=at(x);
    data_type v2=at(y);
    if (v1 == DATA_WITH_ERROR_FLAG || v2 == DATA_WITH_ERROR_FLAG)
        return; // and somehow set error flag!
    data_type t=v1;
    v1 = v2;
    v2 = t;
}

即。如果你不喜欢这样的问题,你需要在任何地方检查正确性。并且有必要支持错误状态的返回以简化错误分析。

答案 1 :(得分:0)

您的代码中存在内存泄漏。您只需将headtail指向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
}

答案 2 :(得分: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;
}