-1

当我试图在 C++ 中将基于循环链表的队列中的最终节点出列时,我遇到了分段错误。成功删除最后一个元素之前的其余元素,它只是最后一个元素,这似乎是解除分配的问题,但是来自终端的唯一日志是分段错误:11。有人可以帮我理解为什么我会得到这种行为. 我在下面粘贴了完整的实现文件,以防它是 Enqueue 函数或构造函数的问题。

#include "BQUEUE.h"
#include <iostream>

using namespace std;

BQUEUE::BQUEUE(): front(nullptr) {}

BQUEUE::BQUEUE(const BQUEUE & queue){
  bqnode *temp = queue.front;
  while (temp->next != queue.front){
    Enqueue(temp->time);
    temp = temp->next;
  }
  Enqueue(temp->time);
}

BQUEUE::~BQUEUE(){
  bqnode *current = front;
  while (current->next != front)
    Dequeue();
}

void BQUEUE::Dequeue(){
  // Empty queue
  if (front == nullptr){
    return;
  } else if (front->next == front){
    front->next = nullptr;
    delete front;
    front = nullptr;
  } else {
    bqnode *temp = front, *current = front;
    while (current->next != front)
      current = current->next;
    front = front->next;
    current->next = front;
    delete temp;
  }
}

void BQUEUE::Print(){
  bqnode *temp = front;
  while (temp->next != front){
    cout << temp->time << endl;
    temp = temp->next;
  }
  cout << temp->time << endl;
}

void BQUEUE::Enqueue(int i){
  bqnode *newNode = new bqnode;
  newNode->time = i;
  if (front == nullptr){
    front = newNode;
    front->next = front;
  } else {
    newNode->next = front;
    bqnode *previous = front;
    if (previous->next == front){
      front->next = newNode;
      return;
    }
    while (previous->next != front)
      previous = previous->next;
    previous->next = newNode;
  }
}

司机:

#include <iostream>
#include "BQUEUE.h"

using namespace std;

int main(){
  BQUEUE k;
  k.Enqueue(60);
  k.Dequeue(); // Segmentation fault occurs here
}

标题:

#ifndef BQUEUE_H
#define BQUEUE_H

class bqnode {
public:
  int time;
  bqnode *prev, *next;
};

class BQUEUE {
  public:
    BQUEUE();
    ~BQUEUE();
    BQUEUE(const BQUEUE &);
    void Enqueue(int);
    void Dequeue( );
    void Print( );
  private:
    bqnode *front;
  };

#endif
4

1 回答 1

2

一个问题是这样的:

void BQUEUE::Dequeue() {
    // Empty queue
    if (front == nullptr) {
        return;
    }
    else if (front->next == front) {  // <-- This is invoked when there is only one node remaining
        front->next = nullptr;
        delete front;
        front = nullptr;  // <--- This is now nullptr
    }
...

然后在析构函数中,您没有检查 is 是否frontnullptr

BQUEUE::~BQUEUE() {
    bqnode *current = front;  // <-- No check to see if front is nullptr
    while (current->next != front)
        Dequeue();
}

然后你访问current->next,这是无效的,因为currentis nullptr。解决方法是简单地检查 if frontis nullptr,如果是,则无事可做。

BQUEUE::~BQUEUE() {
    if ( front )
    {
        bqnode *current = front;  
        while (current->next != front)
            Dequeue();
    }
}
于 2019-03-17T02:23:29.867 回答