【发布时间】:2021-07-08 23:26:12
【问题描述】:
我正在用 C++ 实现一个双向链表,并创建了两个函数,用于将节点添加到具有不同签名的右端,如下所示:
#include <iostream>
using std::cin;
using std::cout;
class LinkedList {
private:
int value;
LinkedList *next;
LinkedList *prev;
public:
LinkedList(int const &x, LinkedList *nextptr = nullptr,
LinkedList *prevptr = nullptr)
: value(x), next(nextptr), prev(prevptr){};
int getValue() const { return value; }
bool hasNext() const { return next ? true : false; }
bool hasPrev() const { return prev ? true : false; }
void setNext(LinkedList *node) { next = node; }
void setPrev(LinkedList *node) { prev = node; }
LinkedList *getNext() const { return next; }
LinkedList *getPrev() const { return prev; }
void addNode(LinkedList *node) {
LinkedList *walker = this;
while (walker->getNext()) {
walker = walker->getNext();
}
walker->setNext(node);
node->setPrev(walker);
}
void addNode(int x) {
LinkedList newNode = LinkedList(x);
LinkedList *node = &newNode;
LinkedList *walker = this;
while (walker->getNext()) {
walker = walker->getNext();
}
walker->setNext(node);
node->setPrev(walker);
} // why does using this lead to an infinite loop?
void printL2R() {
LinkedList *walker = this;
while (walker) {
cout << "<-" << walker->getValue() << "->";
walker = walker->getNext();
}
cout << "\n";
}
};
int main() {
LinkedList l = LinkedList(10);
LinkedList l1 = LinkedList(20);
LinkedList l2 = LinkedList(30);
LinkedList l3 = LinkedList(40);
l.addNode(&l1);
l.addNode(&l2);
l.addNode(&l3);
l.printL2R(); // printL2R works fine till here.
l.addNode(20);
l.printL2R(); // runs infinitely
return 0;
}
代码的预期输出(如果我只使用 addNode(LinkedList* node) 函数可以正常工作:
<-10-><-20-><-30-><-40->
但是,当我使用 addNode(int x) 函数时,我得到一个看起来像这样的无限循环:
<-10-><-20-><-30-><-40-><-20-><-20-><-20-><-20->...on loop
如果有人能帮助我理解为什么会发生这种情况,即使这两个功能都以相同的方式实现(?),我将不胜感激。 谢谢。
【问题讨论】:
-
恕我直言,您的
addNode(int x)应该创建一个新节点,然后调用addNode(LinkedList * node)。这应该减少代码,以便插入只发生在一个地方。 -
@ThomasMatthews,感谢您的回复!我按照您的建议更改了代码。但是,错误仍然存在。
-
您的代码在几个方面很危险。您的直接问题是
LinkedList *node = &newNode;(然后将其添加到数据结构中)正在获取即将结束的帧中堆栈上变量的地址。您也没有考虑内存管理或所有权。您应该查找“5 规则”(以前的 3 规则)。 -
无限循环肯定是由于将列表的下一个节点设置为一个立即被销毁的局部变量 - 然后将内存用于其他用途:打印函数中的变量声明。内存损坏可以做任何事情。
标签: c++ pointers data-structures c++17