繁体   English   中英

取消引用成员指针

[英]Dereferencing a member Pointer

我正在实现一个双向链表,当我尝试访问成员指针指向的对象的成员时,我遇到了段错误。 我的链表由节点组成,节点有一个值和一个下一个和上一个指针

字符串(这是上一个项目的基本实现):

class String{
    public:
    int len;
    char *str;

    String()
    :len(0), str(nullptr){}

    String(char const* S)
    :len(strlen(S)), str(new char[len +1]){
        assert(S != 0);
        strcpy(str, S);
    }

    ~String(){
        delete[]str;
    }
};

Node(我知道这并没有实现“三巨头”,我宁愿将这个类保持在最低限度):

#include <initializer_list>

    template<typename T>
    struct Node{
      T value;
      Node* next;
      Node* prev;

      Node() = default;
      Node(T t, Node* n, Node* p)
      :value(t), next(n), prev(p){}

      Node & operator=(const Node & N){
        value = N.value;
        next = N.next;
        prev = N.prev;
        return *this;
      }
    };

双向链表:

template<typename T>
struct List
{
  List(std::initializer_list<T>);
  Node<T>* head;
  Node<T>* tail;
  List()
  :head(nullptr), tail(nullptr){}

  //copy constructor
  List(const List<T> & l){
    Node<T>* p = l.head;
    head = p;
    Node<T>* past;
    while(p){
      Node<T>* q = new Node<T>;
      *q = *p;
      if(head == p){
        head = q;
      }else{
        past->next = q;
        q->prev = past;
      }
      past = q;
      p = q->next;
    }
    tail = past;
  }


  //copy assignment
  List & operator=(const List & L){
    List temp = L;
    swap (*this, temp);
    return *this;
  }

  Node<T>* getHead()const{
    return head;
  }

  Node<T>* getTail()const{
    return tail;
  }

  void swap(List a, List b){
    Node<T>* temp1 = a.getHead();
    Node<T>* temp2 = a.getTail();

    a.head = b.getHead();
    a.tail = b.tail;
    b.head = temp1;
    b.tail = temp2;
  }

  void push_back(T t){
    Node<T>* p = new Node<T>(t, nullptr, tail);
    if(tail){
      tail->next = p; //Segfault occurs here
    }else{
      head = p;
    }
    tail = p;
  }

  int compare(const List<T> & b)const{
    Node<T>* temp1 = this->head;
    Node<T>* temp2 = b.head;
    while (temp1 != this->tail && temp2 != b.tail) {
      if (temp1->value < temp2->value)
        return -1;
      if (temp2->value < temp1->value)
        return 1;
    }
    if (temp1 == this->tail) {
      if (temp2 != this->tail)
        return -1; // [first1, last1) is a prefix of [first2, last2)
      else
        return 0;  // [first1, last1) and [first2, last2) are equivalent
    }
    else {
      return 1;    // [first2, last1) is a prefix  of [first1, last1)
    }
  }

  size_t size()const{
    size_t n = 0;
    Node<T> *p = head;
    while (p){
      ++n;
      p = p->next;
    }
    return n;
  }

  void clear(){
    Node<T> *p = head;
    while(p){
      Node<T>* q = p-> next;
      delete[] p;
      p = q;
    }
    head = tail = nullptr;
  }

  ~List<T>(){
    clear();
  }
};

template<typename T>
List<T>::List(std::initializer_list<T> list)
{
  for (T const& elem : list)
    push_back(elem);
}

主要的:

int main()
{
    List<String> v1 =  {"a", "b", "c"}; //segfault occurs on second pass of initialization loop
    return 0;
}

任何帮助表示赞赏!

Node(我知道这并没有实现“三巨头”,我宁愿将这个类保持在最低限度):

您应该注意到复制/移动构造函数和赋值运算符仍然作为编译器生成的默认版本提供

为避免在您不想实现三大(或五个)的情况下,您需要明确delete它们:

class String{
    public:
    int len;
    char *str;

    String()
    :len(0), str(nullptr){}

    String(char const* S)
    :len(strlen(S)), str(new char[len +1]){
        assert(S != 0);
        strcpy(str, S);
    }

    // Add these:
    String(const String&) = delete;
    String(String&&) = delete;
    String& operator=(const String&) = delete;
    String& operator=(String&&) = delete;

    ~String(){
        delete[]str;
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM