简体   繁体   English

当我打印单链接列表时,为什么会有一个虚拟节点?

[英]Why there is a dummy node when I am printing a singly linked list?

My code prints an extra node(garbage value) why? 我的代码为什么打印一个额外的节点(垃圾值)? Is there is any issue with my code? 我的代码有问题吗? just let me how to fix it. 让我来解决这个问题。

void push(node **head_ref,int value)  //function to insert a new node on front of the list
{
    node *new_node=(node*)malloc(sizeof(node));
    new_node->data=value;
    new_node->next=*head_ref;
    *head_ref=new_node;
}

void printll(node *head)    //function to print the list
{
    node *temp = head;
    while(temp!=NULL)
    {
        printf("%d ",temp->data);
        temp=temp->next;
    }
}

Actual Output : 实际输出:
45 88 24 34 77 0 45 88 24 34 77 0

Expected Output : 预期产量:
45 88 24 34 77 45 88 24 34 77


Full code: 完整代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cassert>

using namespace std;

struct node
{
    int data;
    node *next;
};

void push(node **head_ref,int value)
{
    node *new_node=(node*)malloc(sizeof(node));
    new_node->data=value;
    new_node->next=*head_ref;
    *head_ref=new_node;
}

void printll(node *head)
{
    node *temp = head;
    while(temp!=NULL)
    {
        printf("%d ",temp->data);
        temp=temp->next;
    }

}

int main()
{
    node *head= (node*)malloc(sizeof(node));
    push(&head,77);
    push(&head,34);
    push(&head,24);
    push(&head,88);
    push(&head,45);
    printll(head);
    printf("\n");
    return 0;
}

When you allocate memory using malloc the memory is not initialized in any way, it's content is indeterminate . 当您使用malloc分配内存时,不会以任何方式初始化内存,它的内容是不确定的 That means that when you allocate the first node (which is a dummy extra node that's not needed) it's next pointer is not null, and dereferencing this indeterminate pointer leads to undefined behavior . 这意味着,当您分配第一个节点(不需要的虚拟额外节点)时,它的next指针不为null,并且取消引用该不确定的指针会导致未定义的行为

The simplest solution? 最简单的解决方案? Considering your code is closer to C than C++, don't allocate memory initially at all, instead just create a pointer and initialize it to NULL : 考虑到您的代码比C比C ++更接近C,因此根本不分配内存,而只是创建一个指针并将其初始化为NULL

node *head = NULL;

One proper way to do it in C++ is to not use malloc at all, instead use the C++ operator new and add a constructor to the node structure which initializes it: 在C ++中执行此操作的一种正确方法是根本不使用malloc ,而使用C ++运算符new并向初始化它的node结构添加构造函数:

struct node
{
    node() : data(0), next(nullptr) {}
    node(int d, node* n) : data(d), next(n) {}

    int data;
    node* next;
};

void push(node** head_ref, int value)
{
    *head_ref = new node(value, *head_ref);
}

...

int main()
{
    node* head = nullptr;
    ...
}

Now you can create a new node and it will have an initial value of 0 , and its next pointer will be a null-pointer. 现在,您可以创建一个新节点,它的初始value 0next指针为空指针。 You can also, as shown above, create and initialize a new node with specific value and next . 如上所示,您还可以创建和初始化具有特定valuenext的新节点。

[Substitute nullptr for 0 if your compiler doesn't support the C++11 nullptr value] [如果您的编译器不支持C ++ 11 nullptr值,则将nullptr替换为0 ]

Instead of this definition 代替这个定义

node *head= (node*)malloc(sizeof(node));

you should write simply 你应该简单地写

node *head = NULL;

or 要么

node *head = nullptr; // C++

Otherwise your program has undefined behaviour because the allocated node for the head was not initialized. 否则,您的程序将具有未定义的行为,因为未初始化头分配的节点。

Also if it is a C++ program you should use operator new instead of C function malloc . 另外,如果它是C ++程序,则应使用运算符new而不是C函数malloc For example function push will look like 例如功能push看起来像

void push( node * &head_ref, int value )
{
    head_ref = new node { value, head_ref };
}

and called like 叫像

push( head, 77 );

Take into account that you have also to write a function that will free the all allocated memory for the list. 考虑到您还必须编写一个函数,该函数将为列表释放所有分配的内存。

You have a dummy node (head itself) in your design. 您的设计中有一个虚拟节点(头部本身)。 So the print function needs to skip that dummy node. 因此,打印功能需要跳过该虚拟节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM