0

我对c编程没有太多经验。我不明白这段代码中的错误是什么。在将此代码放到网上之前,我已经尝试了 5 次。请帮忙。我在这里实现了一个双向链表,其中有两个函数可以将节点添加到列表中,还有一个函数可以显示整个列表。编译成功后,如果我尝试添加一个节点,那么程序会意外结束。

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
struct node
{
    int data;
    struct node* next;
    struct node* prev;
};
void display_list(struct node* ptr);    
void add_node(struct node* ptr)
{
    if(ptr->next==NULL)
    {
        ptr=(struct node*)malloc(sizeof(struct node));
        (ptr->next)->next=NULL;
        (ptr->next)->prev=ptr;
    }
    else        
    {   //traverse the list
        while(ptr->next!=NULL)
        {
            ptr=ptr->next;
        }
        (ptr->next)=(struct node*)malloc(sizeof(struct node));
        (ptr->next)->next=NULL;
        (ptr->next)->prev=ptr;
    }
    printf("\nEnter data : ");
    scanf("%d",((ptr->next)->data));
    display_list(ptr);
}
void display_list(struct node* ptr)
{
    if(ptr->next==NULL)
    {
        printf("%d\n",ptr->data);
    }
    else
    {
        //traverse the list and display each node
        while(ptr->next!=NULL)
        {
            printf("%d--->>>---",ptr->data);
            ptr=ptr->next;
        }
            //display last node
        printf("%d",ptr->data);
    }
}
int main()
{
    int choice;
    struct node* start=NULL;
    again:
    printf("\n1) Add node");
    printf("\n2) Display list");
    scanf("%d",&choice);
    if(choice==1)
        add_node(start);
    else if(choice==2)
        display_list(start);
    else 
        goto again;
    return 0;
}
4

4 回答 4

3

在你的add_node函数中,你有一个if检查 if ptr->nextis的语句NULL,但你从来没有真正检查过ptr 它本身是否是NULL

在您的main函数中,您可以看到第一次调用add_node时,参数确实是NULL,因此该函数中的第一次ptrNULL,并且一旦您的代码尝试检查,您就会遇到问题ptr->next


既然你在评论中问得很好,我会告诉你我对代码重组的意思。

现在,您的实现add_node将 astruct node *作为参数。问题是当你有这样的事情时:

struct node* ptr = NULL;
add_node(ptr);

即使您修改add_node为正确处理NULL参数,返回后ptr其自身的值也不会改变add_node。一种方法是add_node取而代之struct node **。像这样的东西:

void add_node(struct node ** head) {
    struct node * ptr = *head;

    // use ptr like you had before in the old implementation

    *head = ptr; // updating head.
                 // If ptr has changed, this will update head
                 // If it hasn't, then no harm
}

这样,如果你有类似的东西

struct node *foo;
add_node(&foo);

*head = ptr末尾的那一行将add_node使用正确的值更新变量,并且这一次foo add_node返回时更新。

于 2013-10-13T06:37:09.150 回答
0

如果你在这里替换你的行:

struct node* start=NULL;

使用创建根节点的代码:

struct node* start = (struct node*)malloc(sizeof(struct node));

if (start)
{
   start->prev = NULL;
   start->next = NULL;
}

您将传递一个有效节点,然后可以将其“添加到”。

于 2013-10-13T07:08:27.927 回答
0

您正在取消引用无效指针

    ptr=(struct node*)malloc(sizeof(struct node));
    (ptr->next)->next=NULL;
    (ptr->next)->prev=ptr;

你创建 ptr 里面有垃圾,然后你访问它的一个成员ptr->next->next

于 2013-10-13T19:14:50.840 回答
0

终于得到了这个问题的答案,导致代码在这里。我在真正问题所在的区域添加了评论:

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
/////////////////////////////////////////////////////////////////////////////////////
struct node
{
    int data;
    struct node* next;
    struct node* prev;
};
//////////////////////////////////////////////////////////////////////////////////////

***//now add node function also returns a pointer of type node***

struct node* insert_node(struct node* start,int item)
{
    struct node* new_node=(struct node*)malloc(sizeof(struct node));
    new_node->data=item;
    //no availabel heap
    if(new_node==NULL)
    {
        printf("\nNo availabel memory!");
        exit(0);
    }
    //if there is no node in the linked list
    if(start==NULL)
    {
        start=new_node;
        start->next=NULL;
        start->prev=NULL;
    }
    //if there is one node in the linked list
    else
    {
        new_node->next=start;
        new_node->prev=NULL;
        start=new_node;             //start now points to new node
    }
    return start;
}
void display_list(struct node* ptr)    //display function has also been modified
{
    struct node* temp=ptr;
    while(temp)
    {
        printf("%d-->>--",temp->data);
        temp=temp->next;
    }
}
////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    int i;
    struct node* start=NULL;
    for(i=0;i<10;i++)
    {
        start=insert_node(start,i+1);   //function must return a pointer 
            //because the function uses a copy of the pointer and does not modify the
            //original pointer in the main function
    }
    display_list(start);
    return 0;
}
于 2013-10-13T18:20:55.780 回答