通用双链表,创建列表时分配错误

时间:2018-05-31 21:27:24

标签: c++ xcode linked-list

我正在写一个通用的双链表。我收到一些我不太懂的错误:

enter image description here

enter image description here

我不确定我写课程的方式是什么问题,但我无法让它发挥作用。也许这是我创建结构节点部分的方式,但在线搜索似乎这是一个非常标准的方法。

到目前为止,这是我的代码:

#ifndef DoubleLinkedLists_h
#define DoubleLinkedLists_h

template <class T>
class DoubleLinkedLists {
private:

    struct Node {
        T data;
        T* next;
        T* previous;
    };

    Node* head;
    Node* tail;

public:
    // Constructors
    DoubleLinkedLists() : head(nullptr), tail(nullptr) {}
    DoubleLinkedLists(DoubleLinkedLists const& value);
    ~DoubleLinkedLists();

    // Overload operators
    DoubleLinkedLists& operator=(DoubleLinkedLists const& rhs);
    friend std::ostream& operator<<(std::ostream& str, DoubleLinkedLists<T>& data) {
        data.display(str);
        return str;
    }

    // Member functions
    void swap(DoubleLinkedLists& other) noexcept;
    void createNode(const T& theData);
    void createNode(T&& theData);
    void display(std::ostream& str) const;
    void display() const;
    void insertHead(const T& theData);
    void insertTail(const T& theData);
    void insertPosition(int pos, const T& theData);
    void deleteHead();
    void deleteTail();
    void deletePosition(int pos);
    bool search(const T& x);
};

template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists const& value) : head(nullptr), tail(nullptr) {
    for(Node* loop = value->head; loop != nullptr; loop = loop->next) {
        createNode(loop->data);
    }
}

template <class T>
DoubleLinkedLists<T>::~DoubleLinkedLists() {
    while(head != nullptr) {
        deleteHead();
    }
}

template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists const& rhs) {
    DoubleLinkedLists copy(rhs);
    swap(copy);
}

template <class T>
void DoubleLinkedLists<T>::swap(DoubleLinkedLists<T>& other) noexcept {
    using std::swap;
    swap(head, other.head);
    swap(tail, other.tail);
}

template <class T>
void DoubleLinkedLists<T>::createNode(const T& theData) {
    Node* newNode;
    Node* temp = new Node;
    newNode->data = theData;
    newNode->previous = nullptr;
    newNode->next = nullptr;

    if(head == nullptr) {
        head = temp;
        tail = temp;
        temp = nullptr;
    }
    else {
        newNode = head;
        while(newNode != nullptr) {
            newNode = newNode->next;
        }
        newNode->next = temp;
        temp->previous = newNode;
    }
}

template <class T>
void DoubleLinkedLists<T>::createNode(T&& theData) {
    Node* newNode;
    Node* temp = new Node;
    newNode->data = std::move(theData);
    newNode->next = nullptr;

    if(head == nullptr) {
        temp->previous = nullptr;
        head = temp;
    }
    else {
        newNode = head;
        while(newNode->next != nullptr) {
            newNode = newNode->next;
        }
        newNode->next = temp;
        temp->previous = newNode;
    }
}

template <class T>
void DoubleLinkedLists<T>::display(std::ostream &str) const {
    for(Node* loop = head; loop != nullptr; loop = loop->next) {
        str << loop->data << "\t";
    }
    str << "\n";
}

template <class T>
void DoubleLinkedLists<T>::display() const {
    for(Node* loop = head; loop != nullptr; loop = loop->next) {
        std::cout << loop->data << "\t";
    }
    std::cout << "\n";
}



#endif /* DoubleLinkedLists_h */

这是main.cpp文件:

#include <iostream>
#include "DoubleLinkedLists.h"


int main(int argc, const char * argv[]) {
        ///////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////// Double Linked List //////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////
        DoubleLinkedLists<int> obj;
        obj.createNode(2);
        obj.createNode(4);
        obj.createNode(6);
        obj.createNode(8);
        obj.createNode(10);
        std::cout<<"\n--------------------------------------------------\n";
        std::cout<<"---------------Displaying All nodes---------------";
        std::cout<<"\n--------------------------------------------------\n";
        obj.display();


    return 0;
}

修改

#ifndef DoubleLinkedLists_h
#define DoubleLinkedLists_h

template <class T>
class DoubleLinkedLists {
private:

    struct Node {
        T data;
        Node* next;
        Node* previous;
    };

    Node* head;
    Node* tail;

public:
    // Constructors
    DoubleLinkedLists() : head(nullptr), tail(nullptr) {}                  // empty constructor
    DoubleLinkedLists(DoubleLinkedLists const& value);                     // copy constructor
    DoubleLinkedLists<T>(DoubleLinkedLists<T>&& move) noexcept;            // move constuctor
    DoubleLinkedLists<T>& operator=(DoubleLinkedLists&& move) noexcept;    // move assignment operator
    ~DoubleLinkedLists();                                                  // destructor

    // Overload operators
    DoubleLinkedLists& operator=(DoubleLinkedLists const& rhs);
    friend std::ostream& operator<<(std::ostream& str, DoubleLinkedLists<T> const& data) {
        data.display(str);
        return str;
    }

    // Member functions
    void swap(DoubleLinkedLists& other) noexcept;
    void createNode(const T& theData);
    void createNode(T&& theData);
    void display(std::ostream& str) const;
    void display() const;
    void insertHead(const T& theData);
    void insertTail(const T& theData);
    void insertPosition(int pos, const T& theData);
    void deleteHead();
    void deleteTail();
    void deletePosition(int pos);
    bool search(const T& x);
};

template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists const& value) : head(nullptr), tail(nullptr) {
    for(Node* loop = value->head; loop != nullptr; loop = loop->next) {
        createNode(loop->data);
    }
}

template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists<T>&& move) noexcept : head(nullptr), tail(nullptr) {
    move.swap(*this);
}

template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists<T> &&move) noexcept {
    move.swap(*this);
    return *this;
}

template <class T>
DoubleLinkedLists<T>::~DoubleLinkedLists() {
    while(head != nullptr) {
        deleteHead();
    }
}

template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists const& rhs) {
    DoubleLinkedLists copy(rhs);
    swap(copy);
}

template <class T>
void DoubleLinkedLists<T>::swap(DoubleLinkedLists<T>& other) noexcept {
    using std::swap;
    swap(head, other.head);
    swap(tail, other.tail);
}

template <class T>
void DoubleLinkedLists<T>::createNode(const T& theData) {

}

template <class T>
void DoubleLinkedLists<T>::createNode(T&& theData) {
    Node* newNode;
    Node* temp = new Node;
    temp->data = std::move(theData);
    temp->next = nullptr;

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

    }
}

template <class T>
void DoubleLinkedLists<T>::display(std::ostream &str) const {
    for(Node* loop = head; loop != nullptr; loop = loop->next) {
        str << loop->data << "\t";
    }
    str << "\n";
}

template <class T>
void DoubleLinkedLists<T>::display() const {
    for(Node* loop = head; loop != nullptr; loop = loop->next) {
        std::cout << loop->data << "\t";
    }
    std::cout << "\n";
}


template <class T>
void DoubleLinkedLists<T>::deleteHead() {
    Node* old = head;
    head = head->next;
    delete old;
}



#endif /* DoubleLinkedLists_h */

2 个答案:

答案 0 :(得分:2)

对于数据以及下一个和上一个指针,您使用T,当指针应该是Node*类型时,就像头部和尾部一样。

答案 1 :(得分:2)

错误是由next previous Node成员声明为T*而不是Node*引起的。

您的代码中也存在其他一些问题。

  • operator<<需要data作为const引用,因为display()被声明为const(应该是):< / p>

    friend std::ostream& operator<<(std::ostream &str, DoubleLinkedLists<T> const &data)
    
  • operator=未返回任何内容(需要返回*this)。

    此外,它没有处理自我分配的可能性。

    template <class T>
    DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists const& rhs) {
        if (this != &rhs) { // <-- add this
            DoubleLinkedLists copy(rhs);
            swap(copy);
            // alternatively:
            // DoubleLinkedLists(rhs).swap(*this);
        }
        return *this; // <-- add this
    }
    
  • 没有移动构造函数或移动赋值运算符的实现。

    template <class T>
    DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists && value) : head(nullptr), tail(nullptr) {
        value.swap(*this);
    }
    
    template <class T>
    DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists && rhs) {
        rhs.swap(*this);
    }
    
  • createNode()的两个版本中访问错误。

    当您指向有效的newNode实例时,您正在访问Node的成员。

    在第一次访问时,newNode未初始化(您正在初始化temp)。

    head不是nullptr时查找最后一个节点的循环是错误的,导致newNode在您第二次访问其成员时始终最终成为nullptr 。无论如何,循环是不必要的,因为您可以(并且应该)将新节点简单地附加到tail的右侧。

    此外,createNode()的移动版本在tail最初head时未将新创建的节点分配给nullptr

    template <class T>
    void DoubleLinkedLists<T>::createNode(const T& theData) {
        Node* newNode = new Node;
        newNode->data = theData;
        newNode->previous = nullptr;
        newNode->next = nullptr;
    
        if (!head)
            head = newNode;
    
        if (tail) {
            newNode->previous = tail;
            tail->next = newNode;
        }
        tail = newNode;
    }
    
    template <class T>
    void DoubleLinkedLists<T>::createNode(T&& theData) {
        Node* newNode = new Node;
        newNode->data = std::move(theData);
        newNode->previous = nullptr;
        newNode->next = nullptr;
    
        if (!head)
            head = newNode;
    
        if (tail) {
            newNode->previous = tail;
            tail->next = newNode;
        }
        tail = newNode;
    }
    

    或者,你可以让一个人调用另一个,这样你就不必重复两次相同的逻辑:

    template <class T>
    void DoubleLinkedLists<T>::createNode(const T& theData) {
        T copy(theData);
        createNode(std::move(copy));
    }
    
  • 并非真正的错误,但display()的无参数版本可以将std::cout传递给display()的1参数版本,因此您无需复制相同的循环两次:

    template <class T>
    void DoubleLinkedLists<T>::display() const {
        display(std::cin);
    }