C++ “双链表”;“未处理的异常”;错误

C++ “双链表”;“未处理的异常”;错误,c++,data-structures,linked-list,C++,Data Structures,Linked List,我在创建一个双链接列表时,遇到了一个奇怪的错误,花了几个小时调试它,但无法完成,我尝试了一个在线调试器,即使这样也无济于事 程序确实编译并运行,但是崩溃了。我得到的错误是 double Link list.exe中0x770215ee处未处理的异常:0xC0000005:访问冲突写入位置0x00000004 联机调试器结果 在线调试器给出了三个错误,我在下面的代码中已经提到了这三个错误,并给出了注释 我猜类列表的add函数有问题 类节点 #include <iostream> us

我在创建一个双链接列表时,遇到了一个奇怪的错误,花了几个小时调试它,但无法完成,我尝试了一个在线调试器,即使这样也无济于事

程序确实编译并运行,但是崩溃了。我得到的错误是

double Link list.exe中0x770215ee处未处理的异常:0xC0000005:访问冲突写入位置0x00000004

联机调试器结果

在线调试器给出了三个错误,我在下面的代码中已经提到了这三个错误,并给出了注释

我猜类列表的add函数有问题

类节点

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