【问题标题】:Linked list program crash链表程序崩溃
【发布时间】:2016-08-30 09:09:47
【问题描述】:

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

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

所以现在我有一个初始化的“新”指针,错误代码更改为 c00000fd

【问题讨论】:

  • 可能是因为您使用了未初始化的指针:node* head = new node; 会有所帮助
  • @Garf365 你的意思是new 因为这是一个c++问题? :P
  • @KostasRim 已更正;)
  • 阅读一些例子和A good book关于c++。
  • 重新更新:这不是初始化 next 指针的好值。想想新节点的构造函数内部发生了什么。

标签: c++ linked-list crash


【解决方案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;
}

【讨论】:

    【解决方案2】:

    当您尝试使用node::node() 时,您将遇到的第一个错误。如果您查看您的代码:

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

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

    node n; 
    

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

    next = new node;
    

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

    返回链表

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

    1. 它确保没有人可以意外修改您的节点(确保它们以预期的方式运行)
    2. 屏幕上的代码更少。您的用户不会对所有的小细节感到不知所措。 (所有的链表代码都可以保存在另一个文件中,用户可以专注于自己需要做的事情。)

    这是一个示例实现。

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

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

    【讨论】:

      猜你喜欢
      • 2015-07-22
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      • 2019-05-04
      • 2019-05-23
      • 2013-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多