C ++ - 链表 - 复制构造函数

时间:2018-05-18 13:27:15

标签: c++ c++11 constructor

我正在尝试实现复制构造函数,我有一个奇怪的问题。 你能指出我做错了什么吗?

我得到: 双重免费或损坏(输出):0x08936a48

输出错误:

Constructor called...
MyList:
10 --> 20 --> 30 --> 40 --> 
MyList2:
10 --> 20 --> 30 --> 40 --> 
Destructor called...

代码:

#include <iostream>

template <typename T>
class SingleLinkedList{
protected:
    struct Node{
        T data;
        Node * next;
        Node() : next(nullptr) {}
        Node(const T num) : data(num), next(nullptr) {}
    };

private:
    Node * head;
    Node * tail;

public:
    SingleLinkedList();                                             // constructor
    ~SingleLinkedList();                                            // destructor
    SingleLinkedList(const SingleLinkedList &object);               // copy constructor
    SingleLinkedList& operator=(const SingleLinkedList &object);    // copy assignment

    void insert(T const& value);
    void displayList(std::ostream& stream = std::cout) const;

template <typename T>
SingleLinkedList<T>::SingleLinkedList() : head(nullptr), tail(nullptr){
    std::cout << "Constructor called..." << std::endl;
}

template <typename T>
SingleLinkedList<T>::~SingleLinkedList(){
    std::cout << "Destructor called..." << std::endl;
    int index = 1;
    Node * temp = nullptr;
    while(head!=nullptr){
        temp = head;
        head = head->next;
        delete temp;
        //std::cout << "Node number: " << index << " destroyed" << std::endl;
        index++;
    }
}

template <typename T>
SingleLinkedList<T>::SingleLinkedList(const SingleLinkedList<T> &oldList){
    SingleLinkedList<T> * newList = new SingleLinkedList<T>();

    // is it necessary? my constructor by default initializes head and tail with nulls
    head = nullptr;
    tail = nullptr;

    Node * temp = nullptr;
    temp = oldList.head;

    while(temp!=nullptr){
        newList->insert(temp->data);
        temp = temp->next;
    }
}


template <typename T>
void SingleLinkedList<T>::insert(T const& value){
    Node * temp = new Node(value);
    //temp->data = value;
    //temp->next = nullptr;


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

template <typename T>
void SingleLinkedList<T>::displayList(std::ostream& stream) const{
    Node * temp = nullptr;
    temp = head;

    while(temp!=nullptr){
        stream << temp->data << " --> ";
        temp = temp->next;
    }
    stream << std::endl;
}

int main(){

    SingleLinkedList<int> * myList = new SingleLinkedList<int>();
    SingleLinkedList<int> * myList2 = myList;

    myList->insert(10);
    myList->insert(20);
    myList->insert(30);

    myList2->insert(40);

    std::cout << "MyList:" << std::endl;
    myList->displayList();

    std::cout << "MyList2:" << std::endl;
    myList2->displayList();

    delete myList;
    delete myList2;

    return 0;
}

我的“算法”: 1.创建新列表。 2.对于旧列表的每个节点获取数据并将其插入新列表。

我不明白如何使用两个不同的列表我正在释放相同的内存部分。 我是学生,不是专业人士。我要求你理解。

1 个答案:

答案 0 :(得分:2)

你的副本很奇怪。您可以创建一个新列表(为什么?),然后向其中添加元素,而不是将元素添加到正在构建的列表中。之后,您只需退出功能。创建的新列表留在堆上无法访问,即泄露,并且构建的列表保持为空。

你能简单地newList复制列表的元素,而不是某些main,但是在这个元素中?

双重删除是出于另一个原因:在你的myList中你声明了两个指针,myList2myList2,它们都指向内存中的相同列表,后来尝试删除它们都。您可以通过正确构建 SingleLinkedList<int> * myList2{new SingleLinkedList<int>(*myList)};

来快速修复此问题
main

但我建议你在 SingleLinkedList<int> myList; SingleLinkedList<int> myList2(myList); 中删除指针:

->

(并且不要忘记之后将所有.更改为new以下。)

毕竟这不是Java,并非每个生命周期都以{{1}}开头。