链接列表释放内存 - 分段错误

时间:2015-11-05 16:32:16

标签: c++ linked-list segmentation-fault

我的代码中有一个分段错误,这是一个linkedList的实现。你能否告诉我这到底发生了什么?为什么?

我还希望不在函数delete tmp的末尾执行Print(),因为它不是由new分配的,但这会创建另一条错误消息

#include <iostream>
#include <string>
#include <cmath>
#include <vector>
#include <iterator>

using namespace std;

/* ******************************************************* Node ********************************************************* */

template<class T>
class Node
{
    private:
       T _value;
       vector<Node<T>*> children;

    public:
       Node(T value);
       Node(const Node<T>& node);
       void AddChild(Node<T>* node);
       T getValue() const;
       vector<Node<T>*> returnChildren() const;
       void replaceChildrenByNewOnes(vector<Node<T>*> newChildren);
       ~Node();
};

template<class T>
void Node<T>::replaceChildrenByNewOnes(vector<Node<T>*> newChildren)
{
    children=newChildren;
}

template <class T>
Node<T>::Node(T value):_value(value)
{
    children.push_back(NULL);
}

template <class T>
Node<T>::Node(const Node& node):_value(node.getValue()), 
                                 children(node.returnChildren())
{
}

template <class T>
void Node<T>::AddChild(Node* node)
{
    if (children[0]==NULL){children.pop_back();};
    children.push_back(node);
}

template <class T>
T Node<T>::getValue() const
{
    return _value;
}

template <class T>
vector<Node<T>*> Node<T>::returnChildren() const
{
    return children;
}

template <class T>
Node<T>::~Node()
{
    for (typename vector<Node<T>*>::iterator it=children.begin() ; it!=children.end() ; it++)
    {
       delete *it;
    }
}


/* ******************************************************* LinkedList ********************************************************* */

template<class T>
class List
{
    Node<T>* head;

public:
    List(T data);
    void Add(T data);
    void AddAt(int index, T data);
    void Print();
    void DeleteAt(int index);
    int  getEndList();
    ~List();
};

template <class T>
List<T>::~List()
{
    Node<T>* tmp;
    Node<T>* current=head;
    while (current)
    {
        tmp=current;
        current=current->returnChildren()[0];
        delete tmp;
    }
}

template <class T>
List<T>::List(T data){
    head=new Node<T>(data);
}

template <class T>
void List<T>::Print(){
    Node<T>* tmp=head;
    if(tmp==NULL){
        cout <<"The List is Empty" << endl;
        return;
    }
    if(tmp->returnChildren()[0]==NULL){
        cout <<tmp->getValue();
        cout <<"-->NULL" << endl;
    }
    else{
        while(tmp->returnChildren()[0]!=NULL){
            cout<<tmp->getValue();
            cout<<"-->";
            tmp=tmp->returnChildren()[0];
        }
        cout << tmp->getValue();
        cout <<"-->NULL" << endl;
    };
    delete tmp; //je ne l'ai pas alloué par new, faut(il faire un delete?
}

template <class T>
void List<T>::Add(T data)
{
    if(head==NULL){
        head=new Node<T>(data);
        return;
    }
    if(head->returnChildren()[0]==NULL)
    {
        head->AddChild(new Node<T>(data));
    }
    else{
        Node<T>* temp=head;
        while(temp->returnChildren()[0]!=NULL)
        {
            temp=temp->returnChildren()[0];
        }
        temp->AddChild(new Node<T>(data));
    }
}

template <class T>
int List<T>::getEndList()
{
    int endList(1);
    Node<T>* nodeEndList(head);
    while(nodeEndList->returnChildren()[0]!=NULL){
        nodeEndList=nodeEndList->returnChildren()[0];
        endList++;
    }
    return endList++;
} 

template <class T>
void List<T>::AddAt(int index, T data)
{
    int endList=this->getEndList();

    if(index>endList+1)
    {
        cout<< "Your index is out of range" << endl;
        return;
    }

    Node<T>* newNode=new Node<T>(data); //ok
    Node<T>* tmp=head;

    if (index==1)
    {
        newNode->AddChild(tmp);
        head=newNode;
        return;
    }

    if (index>1 && index <=endList)
    {
        int rightSpot=1;
        while(rightSpot!=index-1)
        {
            tmp=tmp->returnChildren()[0];
            rightSpot++;
        }
        Node<T>* nodeBefore=tmp;
        tmp=tmp->returnChildren()[0];
        Node<T>* nodeAfter=tmp;

        newNode->AddChild(nodeAfter);

        vector<Node<T>*> newChild;
        newChild.push_back(newNode);
        nodeBefore->replaceChildrenByNewOnes(newChild);

        return;
    }

    if (index==endList+1)
    {
        Node<T>* tmp=head;
        while(tmp->returnChildren()[0]!=NULL)
        {
            tmp=tmp->returnChildren()[0];
        }
        tmp->AddChild(newNode);
    }
}

int main()
{
    List<int> n(3);
    n.Add(8);
    n.Add(15);
    n.Add(21);
    n.Add(2);
    n.Add(1);
    n.AddAt(1,999);
    n.Print();

}

1 个答案:

答案 0 :(得分:0)

vector<Node*> children();
/* [...] no appends */
Node* p = children[0];

不会产生NULL ptr p,但会抓住空向量的末尾。