【问题标题】:Segmentation Fault (core dumped) when trying to run Queue program - C++尝试运行队列程序时出现分段错误(核心转储) - C++
【发布时间】:2015-03-04 19:40:54
【问题描述】:

每次尝试在 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;
}

编辑:我对代码进行了一些更改......但我仍然遇到同样的错误。我假设我没有正确更新 head 和 tail 和/或 next 和 prev 节点......但我不知道为什么它是错误的或我错过了什么。

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

【问题讨论】:

  • 无关的 Insta 内存泄漏:Node *temp = new Node; temp = ...。这不是 Java。相关:`head = head->next;` 当head 队列中的最后一个节点时,随后将head-&gt;data 发送到cout 不会很好地结束。 head-&gt;data 取消引用空指针,这会调用未定义的行为。

标签: c++ class queue core fault


【解决方案1】:

很多问题:

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

    Node *p = head;
    
    while (p != NULL) 
    {
        cout << p->data << " ";
        p = p->next;
    }
    
  4. remove() 中的 cout &lt;&lt; "Removed: " &lt;&lt; head-&gt;data &lt;&lt; endl; 可能存在 null 指针延迟,因为此时您已经移动了 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;

【讨论】:

  • 非常感谢!这很有帮助。请查看编辑?
猜你喜欢
  • 2013-05-04
  • 2018-10-13
  • 2014-09-30
  • 1970-01-01
  • 2021-12-20
  • 2019-08-11
  • 1970-01-01
  • 2016-08-18
  • 2020-04-21
相关资源
最近更新 更多