自定义类构造中的分段错误

时间:2016-11-17 00:25:20

标签: c++ constructor segmentation-fault

所以我编写了一个浏览器标签结构,我有5个自定义类,Stack,LinkedList,Node(用于链表),Tab和Browser。 LinkedList和Stack本身很好用,但是当我在Browser的构造函数中构造一个LinkedList时,我得到了错误。所以在我的主要部分我只调用Browser()。以下是代码:

LinkedList<T>::LinkedList(){
  front=NULL;
  back=NULL;
}`

Node<T>::Node(){
    prev=NULL;
    next=NULL;
    data=T();
}

Stack<T>::Stack(int capacity){ //capacity is optional, this is the default constructor.
      this->capacity=capacity;
      this->size=0;
      this->items=new T[capacity];
}

`

Browser(){
            selected = NULL;
            //print browser link construction starts
            pages= LinkedList<Tab>(); //This line gives the error.
            closedPages= Stack<Tab>();
            curr_index=-1;
            tab_count=0;
}

Tab(){
    current_page="";
    prevPages=Stack<string>();
    nextPages=Stack<string>();
    closed_index=-1;
}

更有趣的是,当我进行打印插入时,我看到的是它首先启动并完成链接构造(之间不做任何制表构造),然后进行堆栈和制表构造,然后打印“浏览器链接构建开始“然后进入并完成另一个链接构建,然后给出seg错误。所以它进行了两次链接构建甚至强硬我希望它只会做一次吗?

谢谢,如果这是极其容易/愚蠢的事情,请提前抱歉。

EDIT1:完整LinkedList代码

#ifndef _LINKEDLIST_H_
#define _LINKEDLIST_H_

#include <iostream>
#include <cstddef>
#include <stdexcept>
#include "Node.hpp"

using namespace std;

template <class T> 
class LinkedList {
    private:
        /* pointer to the first node */
        Node<T>* front;
        /* pointer to the last node */
        Node<T>* back;

    public:

        LinkedList();
        LinkedList(const LinkedList<T>& ll);
        LinkedList<T>& operator=(const LinkedList<T>& ll);
        ~LinkedList();

        /* returns the first node of the linked list */
        Node<T>& getFront() const;
        /* returns the last node of the linked list */
        Node<T>& getBack() const;
        /* returns the node in given "pos"ition of the linked list */
        Node<T>& getNodeAt(int pos) const;
        /* returns the pointer of the node in given 
           "pos"ition of the linked list */
        Node<T>* getNodePtrAt(int pos) const;

        /* inserts a new node containing "data" 
           after the node "prev" 
           */
        void insert(Node<T>* prev, const T& data);
        /* inserts a new node containing "data" 
           at "pos"ition in the linked list 
           */
        void insertAt(int pos, const T& data);
        /* erases the given "node" from the linked list */
        void erase(Node<T>* node);
        /* erases the node in given "pos"ition from the linked list */
        void eraseFrom(int pos);
        /* clears the contents of the linked list */
        void clear();

        /* inserts a new node containing "data" 
           to the front of the linked list 
           */
        void pushFront(const T& data);
        /* inserts a new node containing "data" 
           to the back of the linked list
           */
        void pushBack(const T& data);

        /* removes the first node */
        void popFront();
        /* removes the last node */
        void popBack();

        /* returns true if the list is empty, false otherwise */
        bool isEmpty() const;
        /* returns the number of items in the list */
        size_t getSize() const;
        /* prints the contents of the linked list 
           one node data per line
           assumes the objects in the node have operator<< overloaded 
           */
        void print() const;

};


template <class T>
LinkedList<T>::LinkedList(){
  cout << "list construction starts" << endl;
  front=NULL;
  back=NULL;
  cout << "list construction ends" << endl;
}

//COPY AND ASSIGMENT
template<class T>
LinkedList<T>::LinkedList(const LinkedList<T>& ll){
  *this=ll;
}
template<class T>
LinkedList<T>&  LinkedList<T>::operator=(const LinkedList<T>& ll){
  clear();
  Node<T>* temp=&(ll.getFront());
  while(temp->getNext()!=NULL){
    pushBack(temp->getData());
    temp->setNext(temp->getNext());
  }
  pushBack(temp->getData());
  return *this;
}
template<class T>
LinkedList<T>::~LinkedList(){
  clear();
}

template <class T>
Node<T>& LinkedList<T>::getFront() const{
  return *front;
}
template <class T>
Node<T>& LinkedList<T>::getBack() const{
  return *back;
}
template <class T>
Node<T>& LinkedList<T>::getNodeAt(int pos) const{
  if(pos<0 or pos>=getSize()){
    throw out_of_range("Bad Input");
  }  
  Node<T>* retval=front;
  for(int i=0;i<pos;i++){
        retval=retval->getNext();
  }
  return *retval;
}
template <class T>
Node<T>* LinkedList<T>::getNodePtrAt(int pos) const{
  if(pos<0 or pos>getSize()){
    throw out_of_range("Bad Input");
  }
  Node<T>* retval=front;
  for(int i=0;i<pos;i++){
        retval=retval->getNext();
  }
  return retval;
}

template <class T>
void LinkedList<T>::insert(Node<T>* prev,const T& data){
  if(prev==NULL){
    pushFront(data);
  }
  else if(prev==back){
    pushBack(data);
  }
  else{
    Node<T>* newNode=new Node<T>();
    newNode->setData(data);
    prev->getNext()->setPrev(newNode);
    newNode->setNext(prev->getNext());
    newNode->setPrev(prev);
    prev->setNext(newNode);
    }
}
template <class T>
void LinkedList<T>::insertAt(int pos,const T& data){
  if(pos==0){
    pushFront(data);
  }
  else if(pos==getSize()){
    pushBack(data);
  }
  else{
    Node<T>* tmp=getNodePtrAt(pos);
    Node<T> newNode;
    newNode.setData(data);
    tmp->getPrev()->setNext(&newNode);
    newNode.setNext(tmp);
    newNode.setPrev(tmp->getPrev());
    tmp->setPrev(&newNode);
  }

}


template <class T>
void LinkedList<T>::pushFront(const T& data){
  Node<T>* newNode=new Node<T>();
  newNode->setData(data);
  if(front==NULL){
    front=newNode;
    back=newNode;
  }
  else {
    newNode->setNext(front);
    front->setPrev(newNode);
    front=newNode;
    newNode->setPrev(NULL);
  }
}

template <class T>
void LinkedList<T>::pushBack(const T& data){
  Node<T>* newNode=new Node<T>();
  newNode->setData(data);
  if(front==NULL){
    front=newNode;
    back=newNode;
  }
  else {
    newNode->setPrev(back);
    back->setNext(newNode);
    back=newNode;
    newNode->setNext(NULL);
  }

}

template <class T>
void LinkedList<T>::erase(Node<T>* node){
  if(node==front){
    popFront();
  }
  if(node==back){
    popBack();
  }
  else {
    node->getNext()->setPrev(node->getPrev());
    node->getPrev()->setNext(node->getNext());
    node->setNext(NULL); node->setPrev(NULL);
  }
  delete node;

}
template <class T>
void LinkedList<T>::eraseFrom(int pos){
Node<T>* tmp=getNodePtrAt(pos);
erase(tmp);
}
template <class T>
void LinkedList<T>::clear(){
  while(!isEmpty()){
    popFront();
  }
}


template <class T>
void LinkedList<T>::popFront(){
  Node<T>* tmp;
  tmp=front;
  if(front==back){
    front=NULL;
    back=NULL;
  }
  else{
    front=front->getNext();
    front->setPrev(NULL);
  }
  delete tmp;
}
template <class T>
void LinkedList<T>::popBack(){
  Node<T>* tmp;
  tmp=back;
  if(front==back){
    front=NULL;
    back=NULL;
  }
  else {
    back=back->getPrev();
    back->setNext(NULL);
  }
  delete tmp;
}

template <class T>
bool LinkedList<T>::isEmpty() const{
  return front==NULL;
}
template <class T>
size_t LinkedList<T>::getSize() const{
  if(front==NULL){
    return 0;
  }
  size_t size=1;
  Node<T>* current=front;
  while(current->getNext()!=NULL){
    size++;
    current=current->getNext();
  }
  return size;
}

template <class T>
void LinkedList<T>::print() const{
  Node<T>* current=front;
  if(front!=NULL){
    while(current->getNext()!=NULL){
        cout << current->getData() << endl;
        current=current->getNext();
    }
    cout << current->getData() << endl;
  }
}

#endif

1 个答案:

答案 0 :(得分:3)

您的分配操作符似乎有问题。在您的浏览器构造函数中,我看到了:

pages = LinkedList<Tab>();

这实际上是不必要的,但却引发了您的问题。在您的浏览器构造函数代码开始时,您的'pages'变量已经默认构造(这就是您在print语句之前看到所有活动的原因)。然后执行使用赋值运算符的赋值。

您的赋值运算符假设源LinkedList对象具有数据,但它没有。它调用getFront()来取消引用'front',它是NULL。你应该先检查它是否为空,我看到你已经有了一个方法(isEmpty())。