链接列表程序崩溃

时间:2016-08-30 09:09:47

标签: c++ linked-list crash

好吧,我正在尝试用很少的代码编写一个链表(一个非常简单的链表)。这是我的代码:

#include <iostream>

using namespace std;

class node
{
public :

    int data = 0;

    node* next;
};

node node_obj;

int main()
{
    node* head;
    node* node_pointer = head;
    node_pointer = node_obj.next;
    node_pointer->data = 4;
    node_pointer = node_obj.next;
    node_pointer->data = 5;
    node_pointer = node_obj.next;
    node_pointer->data = 6;
    node_pointer = node_obj.next;

    return 0;
}

我只是想让它首先工作,这就是没有添加,打印或删除功能的原因。

无论如何,每次运行程序时它都会崩溃,我得到一个错误代码C0000005。

据我所知,这是一个表示内存访问冲突的错误,但我找不到解决方案。 更新: 我改变了我的代码,现在它看起来像这样(仅包括更改的部分):

class node
{
public :
    node();
    int data = 0;
    node* next;
};
node::node()
{
    next = new node;
}

所以现在我有一个初始化的'new'指针,错误代码改为c00000fd

2 个答案:

答案 0 :(得分:1)

首先,在询问此类问题之前,您应该使用调试器。你代码中的问题是:

node node_obj;

int main()
{
    node* head;
    node* node_pointer = head; // Warning: dead storage. You never use the value you initialized here.
    node_pointer = node_obj.next; // node_obj.next was never initialized, so now node_pointer points nowhere.
    node_pointer->data = 4; // And here you use nowhere-pointing pointer to 
    // access structure member. According to the Standard,
    // it's [undefined behavior][1] which in practice usually leads to application crash.
    // All subsequent lines suffer from the same issue.
    node_pointer = node_obj.next;
    node_pointer->data = 5;
    node_pointer = node_obj.next;
    node_pointer->data = 6;
    node_pointer = node_obj.next;

    return 0;
}

可能你想写这样的东西:

node *head;

int main()
{
    head = new node;
    node *node_pointer = head;
    node_pointer->data = 4;
    node_pointer->next = new node;
    node_pointer = node_pointer->next;
    node_pointer->data = 5;
    node_pointer->next = new node;
    node_pointer = node_pointer->next;
    node_pointer->data = 6;
    node_pointer->next = nullptr; // List end marker.
    return 0;
}

答案 1 :(得分:0)

您将获得的第一个错误是,当您尝试使用node::node()时。如果你看一下你的代码:

...
node::node()
{
    next = new node;
}
...

node::node()是类的构造函数。类的构造函数是在创建该类的实例时将执行的函数。假设您创建了一个新节点:

node n; 
调用

node::node()。但是,嘿,它在做什么?

next = new node;

它正在创建一个新节点......这意味着再次呼叫node::node(),并再次无限制地呼叫。这就是你的程序崩溃的原因。

返回链接列表

如果要编写链表,则不仅需要节点。理想情况下,您希望封装所有节点,使其对使用链接列表库的任何人隐藏。我不会详细介绍所有的教科书信息,而是简要介绍一下:

  1. 确保没有人可以意外地修改您的节点(确保它们以预期的方式运行)
  2. 屏幕上的代码较少。您的用户不会被所有细节所淹没。 (所有链表代码都可以保存在另一个文件中,用户可以专注于他/她需要做什么。)
  3. 这是一个示例实现。

    #include <iostream>
    
    // Declaration can be put into LinkedList.h
    struct node {
        node* next_node;
        char* some_data;
    
        node()
        {
            next_node = nullptr;
        }
    };
    
    class LinkedList
    {
        node* head;
        node* tail;
    
    public:
        LinkedList();
        ~LinkedList() { /* if you do this properly, you need to clear up all the nodes you have created... */}
        void AddNode(char* data);
        void PrintNodeData();
    };
    
    
    // Method implementation (The details) can be put into LinkedList.cpp
    
    
    LinkedList::LinkedList()
    {
        head = nullptr;
    }
    
    void LinkedList::AddNode(char* data)
    {
        node* new_node = new node();
        new_node->some_data = data;
    
        if (head == nullptr)
        {
            // initialise the first node
            head = new_node;
        }
        else
        {
            node*n = head;
            while (n->next_node != nullptr)
            {
                // move on to the next node
                n = n->next_node;
            }
            n->next_node = new_node;
        }
    }
    void LinkedList::PrintNodeData()
    {
        // Loop through all the nodes 
        for (node*n = head; n != nullptr; n = n->next_node)
        {
            std::cout << "Data: " << n->some_data << std::endl;
        }
    }
    
    // this is all the code the user has to pay attention to
    int main()
    {
        LinkedList ll;
        ll.PrintNodeData(); // prints nothing, since head == nullptr at this point
        ll.AddNode("Data for my 1st node.");
        ll.AddNode("Data for my 2nd node.");
        ll.AddNode("Data for my 3rd node.");
        ll.AddNode("Data for my 4th node.");
        ll.PrintNodeData(); // prints all the data
        return 0;
    }
    

    希望这会有所帮助,我希望您喜欢自我发现之旅。 : - )