C++ “双链表”;“未处理的异常”;错误
我在创建一个双链接列表时,遇到了一个奇怪的错误,花了几个小时调试它,但无法完成,我尝试了一个在线调试器,即使这样也无济于事 程序确实编译并运行,但是崩溃了。我得到的错误是 double Link list.exe中0x770215ee处未处理的异常:0xC0000005:访问冲突写入位置0x00000004 联机调试器结果 在线调试器给出了三个错误,我在下面的代码中已经提到了这三个错误,并给出了注释 我猜类列表的add函数有问题 类节点C++ “双链表”;“未处理的异常”;错误,c++,data-structures,linked-list,C++,Data Structures,Linked List,我在创建一个双链接列表时,遇到了一个奇怪的错误,花了几个小时调试它,但无法完成,我尝试了一个在线调试器,即使这样也无济于事 程序确实编译并运行,但是崩溃了。我得到的错误是 double Link list.exe中0x770215ee处未处理的异常:0xC0000005:访问冲突写入位置0x00000004 联机调试器结果 在线调试器给出了三个错误,我在下面的代码中已经提到了这三个错误,并给出了注释 我猜类列表的add函数有问题 类节点 #include <iostream> us
#include <iostream>
using namespace std;
class node
{
private:
int data;
node *prev_pointer;
node *next_pointer;
public:
int get_data()
{
return data;
}
void set_data(int data)
{
this->data = data;
}
node* get_prev_ptr()
{
return prev_pointer;
}
void set_next_ptr(node *Node)
{
next_pointer = Node;
}
node* get_next_ptr()
{
return next_pointer;
}
void set_prev_ptr(node *hi)
{
prev_pointer = hi; //First error
}
};
PreEndum:读取调试程序输出:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400d20 in node::set_prev_ptr (this=0x0, hi=0x614c60) at main.cpp:46
46 prev_pointer = hi;
注意this=0x0
。所有的类方法都有一个this指针,这样它们就知道要对许多可能的实例中的哪一个进行操作。此处此
指向空值。程序无法从空对象获取有效的prev\u指针。这告诉您,要找到问题的真正原因,您需要找出此
无效的原因
这就是调用堆栈的作用。您可以向上移动堆栈,以找出此被销毁的位置。我们可以看到,set_prev_ptr
ui在get_next_ptr
和get_next_ptr
的输出上被调用,返回next_指针
。首先要看的地方是下一个指针。将newnode->next_pointer
放入“Display Expressions”显示next_pointer
为空
那么为什么next\u指针为空?我们找到了几行代码
newnode->set_next_ptr(cursor->get_next_ptr())
所以我们查看cursor->next_pointer
,发现它是空的。现在我们进入原始帖子并绘制链表,因为它比反复运行调试器要快得多
调试链表的最好方法是用铅笔和纸:画出来。您将看到,在添加10之后,列表如下所示
head <-> 10 -> NULL
cursor -> 10 -> NULL
lastnode -> 10 -> NULL
尝试
11 -> NULL -> 11;
那么
需要保护它
此外,重新思考
lastnode = cursor;
因为游标
的下一个指向新节点
显然游标
不是最后一个节点。根据光标
指向的位置,新节点
也可能不是最后一个节点
建议:
提供那些完全开放的next和prev访问器会破坏节点的封装,因为任何人都可以使用这些访问器来做任何他们想做的事情节点
。您还可以声明成员变量public
,以节省时间
对于列表
成为节点
的朋友
,或者节点是所有公共
访问(或结构
)并封装在列表
中,远离窥探者的眼睛,这看起来是一个很好的例子。无论哪种方式,都会丢失访问器。调试器只会帮助您查找问题。它不会为你发现问题add
在尝试使用newnode
之前,不会检查它是否被赋予了非空指针。。它检查光标
是否不为空,但检查光标
的下一步是否不为空。
head <-> 10 <-> 11 -> NULL
cursor -> 11 -> NULL
lastnode -> 10 -> 11 -> NULL
(newnode->get_next_ptr())->set_prev_ptr(newnode);
11 -> NULL -> 11;
if (newnode->get_next_ptr() != NULL)
lastnode = cursor;