c++链表队列指针导致未定义行为



我已经看过问题了,还没有看到我的答案。大多数人使用这些结构体,测试参考代码后,我看到结构体版本是功能性的,但是,为什么是类版本不是?

#include <iostream>
using namespace std;
// I'm still bad at pointer logic but it makes sense.
// REFERENCES
// https://www.geeksforgeeks.org/queue-linked-list-implementation/
// stack linked list assignment earlier in semester
// https://stackoverflow.com/questions/29787026/c-queue-from-linked-list
class Node {
public:
int data;
Node *next;         // controls flow of nodes
};
class Queue {
public:
Queue();
~Queue();
void enQueue(int data);
void deQueue();
bool isEmpty();

//private: all set to public because I don't want to make a print function
Node *front;
Node *rear;
int counter;
};
Queue::Queue()
{

front = NULL;
rear  = NULL;

}
Queue::~Queue() {

if (rear == NULL && front == NULL)
{
cout << "Nothing to clean up!" << endl;
}
else
{
cout << "Delete should be happening now...";
}
}
void Queue::enQueue(int data) {
// create new node of queue structure
Node *temp  = new Node;
temp->data  = data;

// write like this line below if not temp->data = data;
// Node *temp = new Node(data); 

// if the queue is empty, first node.
if (rear == NULL)
{
front = temp;
rear  = temp;
return;
}

// assign data of queue structure
rear->next  = temp; // point rear pointer to next pointer = assign to temp
rear = temp; // assign rear to temp keep front pointer at beginning fifo
}
void Queue::deQueue()
{
// if queue is empty, return NULL
if (front == NULL)
{
cout << "Queue is empty, sorry!";
return;
}

Node*   temp = front;       // assign front 

//problem here
front = front->next;        // move front one node ahead

if(front == NULL)
{
rear = NULL;
}
delete (temp);

return;
}

bool Queue::isEmpty() 
{
//   cout << "functions";
//   cout << endl;
return (front == NULL && rear == NULL);
}
int main()
{
Queue yay;
yay.isEmpty();
yay.deQueue();
cout << endl;
yay.enQueue(5);
yay.enQueue(6);

cout << "Queue Front : " << (yay.front)->data << endl;
yay.deQueue();
cout << "After deqQueue " << endl;
cout << "Queue Front : " << (yay.front)->data << endl;
yay.deQueue();
cout << "Queue Front : " << (yay.front)->data << endl;
yay.deQueue(); // <- Problem here
yay.deQueue();
cout << "completed" << endl;
}

我已经把问题隔离到第90行

//problem here
front = front->next;        // move front one node ahead

会导致int main()中的代码不打印

yay.deQueue(); // <- Problem here
yay.deQueue();
cout << "completed" << endl;

我知道我在指针指导等方面很弱,所以如果能告诉我我没有看到的东西会很感激,我已经戳了一段时间了,没有解决。

此链接用于通过在线gdb的代码

https://onlinegdb.com/0B0KzcHMa

This is the output with line 
Queue is empty, sorry!
Queue Front : 5
After deQueue
Queue Front : 6
And the output with line 90 and 96 commented out //96 commented to avoid double free

Queue is empty, sorry!
Queue Front : 5
After deQueue
Queue Front : 5
Queue Front : 5
completed
Delete should be happening now...

Now I know, I know I should be better at this traversal of nodes business 
but, I am not seeing it and this may help me remember it in the future :X
I believe its a simple fix but, everything I try reaches the former output
rather than the later with intended data represented, I believe it is
nexting out into random memory making memory leak or memory pointing wherever
thus it never goes back to main to complete terminal messages

问题就在这里:

Queue yay;
yay.isEmpty();
yay.deQueue();
cout << endl;
yay.enQueue(5);
yay.enQueue(6);

cout << "Queue Front : " << (yay.front)->data << endl;
yay.deQueue();
cout << "After deqQueue " << endl;
cout << "Queue Front : " << (yay.front)->data << endl;
yay.deQueue();
cout << "Queue Front : " << (yay.front)->data << endl; // <<==== HERE

插入了两个元素5和6。然后一个被爆了,然后另一个。这意味着yay.front现在是nullptr根据你的deQueue逻辑读取列表的末尾。因此,读取(yay.front)->data调用未定义行为通过解引用一个无效的指针(在本例中是一个包含nullptr的指针)。

以某种方式取消引用,代码就不会再出错了。

最新更新