尝试 运行 队列程序时出现分段错误(核心已转储)- C++

Segmentation Fault (core dumped) when trying to run Queue program - C++

每次尝试在 Linux 上使用 g++ 运行 我的代码时,我总是收到分段错误(核心转储)错误。它编译正常,但随后发生了......所有功能(删除,添加和打印)似乎都有同样的问题,我似乎无法弄清楚出了什么问题......请heeeelppp。

#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;
}

编辑:我对代码做了一些更改...但我仍然遇到同样的错误。我假设我没有正确更新头部和尾部 and/or 下一个和上一个节点......不过我不知道为什么它是错误的或者我遗漏了什么。

#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;
}

很多问题:

  1. 您有一个双链接 Node 但从未在 add/remove 方法中更新其 prev 成员。
  2. 您正在跟踪 Queue head/tail,但是当您 add/remove 节点时没有正确更新它们。
  3. 您在 printQueue() 中的正向和反向循环都是错误的,并且会导致任何具有 2 个或更多元素的队列的无限循环。队列输出应该是这样的:

    Node *p = head;
    
    while (p != NULL) 
    {
        cout << p->data << " ";
        p = p->next;
    }
    
  4. remove()cout << "Removed: " << head->data << endl; 中可能 null 指针顺从,因为此时您已经移动了 head 指针。将 head 移到 cout.

  5. 之后
  6. Queue::remove() Node *temp = new Node; 内存泄漏。就做 Node* temp = head;.
  7. Queue::printQueue() Node *p = new Node; 内存泄漏。这里不需要分配节点。
  8. 空队列的 remove() 中没有 return 值。

编辑

将节点添加到空列表时不要忘记初始化 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;