2015-03-04 4 views
0

Я все время получаю ошибку с ошибкой сегментации (ядро сбрасывания) при каждом запуске моего кода с g ++ в Linux. Он компилируется отлично, но тогда это происходит ... Все функции (удалить, добавить и распечатать), похоже, имеют одинаковую проблему, я не могу понять, что не так ... Пожалуйста, heeeelppp.Ошибка сегментации (сбрасывание ядра) при попытке запустить программу очереди - C++

#include <iostream> 
#include <string> 

using namespace std; 

//Create a node struct 
struct Node { 
    int data; 
    Node *next; 
    Node *prev; 
}; 

class Queue { 
private: 
    Node *head; 
    Node *tail; 
    int size; 
public: 
    Queue(); 
    ~Queue(); 
    void add(int d); 
    int remove(); 
    bool isEmpty(); 
    void printQueue(bool o); 
}; 


//set to NULL 
Queue::Queue() { 

    head = tail = NULL; 
    size = 0; 

} 

//destructor 
//call remove until empty 
Queue::~Queue() { 

    while (!isEmpty()) 
    remove(); 
} 

//adds a node with the given data at the back of the queue 
void Queue::add(int d) { 

    Node *temp = new Node(); 
    temp->data = d; 
    temp->next = NULL; 

    if (isEmpty()) { 

    //add to head 
    head = temp; 

    } else { 

    //append 
    tail->next = temp; 
    tail = temp; 

    cout << "Added: " << tail->data << endl; 
    } 

    size++; 
} 

//removes the node at the head of the queue and returns its data 
int Queue::remove() { 

    if (isEmpty()) { 

    cout << "The queue is empty." << endl; 

    } else { 

    Node *temp = new Node; 
    temp = head; 
    int value = head->data; 

    //moves pointer to next node 
    head = head->next; 

    cout << "Removed: " << head->data << endl; 

    size--; 
    delete temp; 
    return value; 

    } 
} 

//determines if the queue is empty 
bool Queue::isEmpty() { 
    return (size == 0); 
} 

//prints the contents of the queue from front to back, or front 
//to back, depending on the value of the parameter 
void Queue::printQueue(bool o) { 

    if (isEmpty()) { 

    cout << "The queue is empty." << endl; 

    } else { 

    Node *p = new Node; 

    if (o == true) { 

     cout << "Printing in front to back:" << endl; 

     //print front to back 
     while(p != NULL) { 
     p = head; 
     cout << p->data << " "; 
     p = p->next; 
     } 

    } else if (o == false) { 

     cout << "Printing in back to front:" << endl; 

     //print back to front 
     while (p != NULL) { 
     p = tail; 
     cout << p->data << " "; 
     p = p->prev; 
     } 
    } 
    } 
} 

int main() { 

    Queue q; 

    q.add(8); 

    return 0; 
} 

EDIT: Я внесла некоторые изменения в код ... Но я все еще получаю ту же ошибку. Я предполагаю, что я не обновляю голову, хвост и/или следующий и предыдущий узлы правильно ... Я не знаю, почему это неправильно или что я пропал без вести.

#include <iostream> 
#include <string> 

using namespace std; 

struct Node { 
    int data; 
    Node *next; 
    Node *prev; 
}; 

class Queue { 
private: 
    Node *head; 
    Node *tail; 
    int size; 
public: 
    Queue(); 
    ~Queue(); 
    void add(int d); 
    int remove(); 
    bool isEmpty(); 
    void printQueue(bool o); 
}; 

Queue::Queue() { 

    head = tail = NULL; 
    size = 0; 

} 

Queue::~Queue() { 

    while (!isEmpty()) 
    remove(); 
} 

void Queue::add(int d) { 

    Node *temp = new Node; 
    temp->data = d; 
    temp->next = NULL; 
    temp->prev = tail; 

    if (isEmpty()) { 

    //add to head 
    head = temp; 

    } else { 

    //append 
    tail->next = temp; 
    tail = temp; 

    cout << "Added: " << tail->data << endl; 
    } 
    size++; 
} 

int Queue::remove() { 

    if (isEmpty()) { 

    cout << "The queue is empty." << endl; 

    return 0; 

    } else { 

    Node *temp = head; 
    int value = head->data; 

    cout << "Removed: " << head->data << endl; 

    //moves pointer to next node 
    head = head->next; 
    head->prev = NULL; 

    size--; 
    delete temp; 
    return value; 
    } 
} 

bool Queue::isEmpty() { 
    return (size == 0); 
} 

void Queue::printQueue(bool o) { 

    if (isEmpty()) { 

    cout << "The queue is empty." << endl; 

    } else { 

    Node *p; 

    if (o == true) { 

     p = head; 

     cout << "Printing in front to back:" << endl; 

     //print front to back 
     while(p != NULL) { 
     cout << p->data << " "; 
     p = p->next; 
     } 

    } else if (o == false) { 

     p = tail; 

     cout << "Printing in back to front:" << endl; 

     //print back to front 
     while (p != NULL) { 
     cout << p->data << " "; 
     p = p->prev; 
     } 
    } 
    } 
} 

int main() { 

    Queue q; 

    q.add(9); 
    q.add(10); 
    q.add(11); 
    q.add(12); 
    q.add(13); 
    q.add(14); 
    q.add(15); 
    q.add(16); 

    q.remove(); 
    q.remove(); 

    q.printQueue(true); 
    q.printQueue(false); 

    return 0; 
} 
+0

Несвязанный, утечка Insta-памяти: 'Узел * temp = новый узел; temp = ... '. Это не Java. Связано: 'head = head-> next;' с последующей отправкой 'head-> data' в' cout' не закончится хорошо, когда 'head' * был * последним узлом в очереди. 'head-> data' разделяет нулевой указатель, который вызывает неопределенное поведение. – WhozCraig

ответ

2

Много проблем:

  1. У вас есть двойной связанный Node, но никогда не обновлять свой prev элемент в добавить/удалить методы.
  2. Вы отслеживаете как головку/хвост Queue, но не обновляете их при добавлении/удалении узлов.
  3. Неправильные и прямые, и обратные петли в printQueue() являются неправильными и приводят к бесконечному циклу для любой очереди с двумя или более элементами. Выход очереди должен быть только что-то вроде:

    Node *p = head; 
    
    while (p != NULL) 
    { 
        cout << p->data << " "; 
        p = p->next; 
    } 
    
  4. Возможных null указателя почтительности в remove() на cout << "Removed: " << head->data << endl;, так как вы уже перенесли head указатель на этот раз. Переместите head после cout.

  5. Утечка памяти в Queue::remove() по адресу Node *temp = new Node;. Просто сделайте Node* temp = head;.
  6. Утечка памяти в Queue::printQueue() по адресу Node *p = new Node;. Вам не нужно выделять узел здесь.
  7. Неверное количество символов в remove() для пустой очереди.

Редактировать

Не забудьте инициализировать tail при добавлении узла в пустой список:

if (isEmpty()) { 
    head = temp; 
    tail = temp; 
} 

Чтобы удалить узел из головы непустого списка это должно быть примерно так:

Node *temp = head; 
head = head->next; 
if (head) head->prev = NULL; 
size--; 
delete temp; 
if (isEmpty()) tail = NULL; 
+0

Большое вам спасибо! Это очень помогло. См. Редактирование? – pinkcs