2013-10-13 4 views
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; 
} 

ответ

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; 
} 
+0

А, я понимаю, что ты сделал. Также действительный вариант: –

3

В вашей add_node функции, у вас есть if заявление, чтобы проверить, если ptr->next является NULL, но вы никогда не проверить, если ptrсам является NULL.

В вашей main функции, вы можете увидеть, что первый раз, когда вы звоните add_node, аргумент действительно NULL, и, следовательно, первый раз в этой функции, ptr является NULL, и у вас есть вопросы, как только ваш код пытается проверьте ptr->next.


Поскольку вы прекрасно ответили на комментарии, я покажу вам, что я имел в виду с реструктуризацией кода.

В настоящий момент ваша реализация add_node принимает в качестве аргумента struct 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 возвращается.

+0

В отличие от «goto» в стороне, необходимо будет провести некоторую реструктуризацию кода, чтобы исправить это, поскольку первая вставка изменяет заголовок списка. –

+0

После изменения функции add_node и display_list функция отображения печатает значение мусора. – pacman7845421

+0

@AkashRana Как я уже сказал, вам нужно сделать некоторую реструктуризацию, чтобы правильно добавить этот первый элемент. Если у вас есть переменная в вашей основной функции, которая должна хранить указатель на голову списка и просто передать этот указатель на 'add_node', вызов' add_node' фактически не изменяет то, что хранит эта переменная. –

0

Если вы замените строку здесь:

struct node* start=NULL; 

с кодом, который создает корневой узел:

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

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

вы будете передавать действительный узел, который затем может быть «добавлен».

+1

Да, но это создает дополнительный узел в начале, который никогда не используется. –

+0

@DennisMeng После запуска кода функция отображения, выполняемая после функции add_node, выводит значения выводов мусора: 3109872 --- >>> --- 3962592 и хотя есть инструкция goto сразу после операторов if, выполнение программы останавливается, вы думаете есть также ошибка в функции отображения – pacman7845421

+0

Справедливая точка - хотя она все равно может соответствовать требованиям пользователя. Зависит от того, является ли избыточный корневой узел проблемой в его случае ... – Baldrick

0

Вы derefencing недопустимых указателей

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

создать PTR с мусором в нем, вы получите доступ к члену его ptr->next->next

Смежные вопросы