2013-07-29 128 views
1

請參閱下面給出的這個程序。它在delete_node函數結束時崩潰。請讓我知道發生了什麼問題。它在delete_node(5)調用結束時崩潰。調用delete_node後的printf語句不會執行。鏈接列表的分段錯誤

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<stdbool.h> 

typedef struct _list{ 
    int data; 
    struct _list *next; 
}list; 

list* create_list(int val); 
list* add_list(int val, bool ad_end); 
int delete_node(int val); 
void print_list(void); 
list* head = NULL; 
list* curr = NULL; 

int main() 
{ 
    int val = 10; 
    list* mylist; 
    mylist = create_list(5); 
    add_list(val, true); 
    add_list(20, true); 
    add_list(30, true); 
    add_list(25, true); 
    print_list(); 
    delete_node(5); 
    printf("\n I am here in main \n"); 
    print_list(); 
    return 0; 
} 

list* create_list(int val) 
{ 
    list* ptr =(list*) malloc(sizeof(list)); 
    head = curr = ptr; 
    ptr->data = val; 
    ptr->next = NULL; 
    return ptr; 
} 

list* add_list(int val, bool add_end) 
{ 
    list* ptr =(list*) malloc(sizeof(list)); 
    ptr->data = val; 
    ptr->next = NULL; 
    if(add_end) { 
     curr->next = ptr; 
     curr = ptr; 
    } else { 
     ptr->next = head; 
     head = ptr; 
    } 
    return ptr; 
} 

int delete_node(int val) 
{ 
    list* tmp = NULL; 
    list* prev; 

    tmp = head; 
    while(tmp){ 
     if(tmp->data == val) { 
      printf(" Found the node to be deleted\n"); 
      prev->next = tmp->next; 
      if(tmp == head) { 
       head = tmp->next; 
      } 
      free(tmp); 
      printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next); 
      break; 
     } else { 
      prev = tmp; 
      tmp = tmp->next; 
     } 
     printf("Node to be deleted not found \n"); 
    } 
    return 1; 
} 

void print_list(void) 
{ 
    list* tmp = head; 
    while(tmp != NULL) { 
     printf("addr %p\t addr next %p\n", tmp, tmp->next); 
     printf(" Data is %d \n", tmp->data); 
     tmp = tmp->next; 
    } 
    printf("\n"); 
} 
+1

你嘗試在調試器中運行的代碼?這可以幫助您更快速地找到問題,而不僅僅是要求其他人爲您進行調試。 –

+2

嘗試刪除'delete_node'處的第一個元素時,未設置'prev'。 – BLUEPIXY

+2

這不是你的錯誤,但prev-> next = tmp-> next;如果prev未初始化(即數據== val對於第一個值爲真),將成爲段錯誤的源。 – LostBoy

回答

1

delete_node(int val)prev指針沒有初始化。陳述prev->next = tmp->next;給出未定義的行爲。初始化指針:

list * prev = head; 

此外,printf語句跟在free(tmp);聲明之後。 printf將在內存中打印已經解除分配的變量。免費通話應遵循printf聲明。

printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next); 
free(tmp); 
1

delete_node,你聲明的變量prev,但你不指定任何值,給它:

list* prev; 

由於所需的值(5)是第一個列表元素,就會執行這個聲明:

prev->next = tmp->next; 

prev不確定的,因此釋放出SegmentFault。

這就是導致錯誤的原因。

最簡單的辦法就是到時候想元素是通過設置prev爲NULL聲明和檢查,如果它是在while循環空的第一個處理的話:

... 
int delete_node(int val) 
{ 
    list* tmp = NULL; 
    list* prev = NULL; 

    tmp = head; 
    while(tmp){ 
     if(tmp->data == val) { 
      printf(" Found the node to be deleted\n"); 
     if (prev) { 
      prev->next = tmp->next; 
     } 
     ... 

你也應該考慮做它沒有全局變量。

3

這是你的代碼糾正後,它現在工作絕對好,順便說一句,這不是一個好的方式,使鏈表。

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<stdbool.h> 

typedef struct _list{ 
    int data; 
    struct _list *next; 
}list; 

list* create_list(int val); 
list* add_list(int val, bool ad_end); 
int delete_node(int val); 
void print_list(void); 
list* head = NULL; 
list* curr = NULL; 

int main() 
{ 
    int val = 10; 
    list* mylist; 
    mylist = create_list(5); 
    add_list(val, true); 
    add_list(20, true); 
    add_list(30, true); 
    add_list(25, true); 
    print_list(); 
    delete_node(5); 
    printf("\n I am here in main \n"); 
    print_list(); 
    return 0; 
} 

list* create_list(int val) 
{ 
    list* ptr =(list*) malloc(sizeof(list)); 
    head = curr = ptr; 
    ptr->data = val; 
    ptr->next = NULL; 
    return ptr; 
} 

list* add_list(int val, bool add_end) 
{ 
    list* ptr =(list*) malloc(sizeof(list)); 
    ptr->data = val; 
    ptr->next = NULL; 
    if(add_end&&head!=NULL) { 

      while(curr->next!=NULL){ 
       curr= curr->next; 

       } 
     curr->next=ptr; 
     curr = ptr; 
    } else { 
     ptr->next = head; 
     head = ptr; 
    } 
    return ptr; 
} 

int delete_node(int val) 
{ 
    list* tmp = NULL; 
    list* prev; 

    tmp = head; 
    while(tmp->next!=NULL){ 
     prev=tmp; 

      if(tmp == head&&head->next!=NULL) { 
       head = tmp->next; 

      free(tmp); 
      printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next); 
      break; 
      } 

      if(tmp->data == val) { 
      printf(" Found the node to be deleted\n"); 
       tmp=tmp->next; 
      prev->next=tmp->next; 
      free(tmp); 
      printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next); 
      break; 

     } else{ 
     printf("Node to be deleted not found \n"); 
} 
    } 
    return 1; 
} 

void print_list(void) 
{ 
    list* tmp = head; 
    while(tmp != NULL) { 
     printf("addr %p\t addr next %p\n", tmp, tmp->next); 
     printf(" Data is %d \n", tmp->data); 
     tmp = tmp->next; 
    } 
    printf("\n"); 
} 

請去通過我實現了這個鏈接列表,我相信會更容易理解和代碼

#include<stdio.h> 
#include<malloc.h> 
#include<stdlib.h> 


    struct node{ 

     char data; 
     struct node *next; 
     }; 

    struct node *head=NULL; 



    void printMenu(); 
    void getUserSelection(int *); 
    void performOperation(int); 
    void display(void); 
    void addNodeAtBeginning(void); 
    struct node* createNode(void); 
    void displayLinkedList(void); 
    void addNodeAtEnd(void); 
    void getDataFromUser(char*); 
    void addAtuserSpecificLocation(void); 
    int getLocationFromUser(void); 
    void deleteFirstNode(void); 
    void deleteLastNode(void); 
    void deleteFromAspecificPosition(void); 
    void deleteEntireList(void); 

int main(){ 


    int option=0; 


    while(9!=option){ 
        printMenu(); 
        getUserSelection(&option); 
        performOperation(option); 
    } 


    getchar(); 

    return 0; 


} 

void printMenu(){ 


     printf("\n"); 
     printf("\n***********MENU***************\n"); 
     printf("1) Add a node at the beginning\n"); 
     printf("2) Add a node at the end\n"); 
     printf("3) Add a node at a user selected position\n"); 
     printf("4) Delete first Node\n"); 
     printf("5) Delete last Node\n"); 
     printf("6) Delete node at a user selected position\n"); 
     printf("7) Display\n"); 
     printf("8) Delete entire list\n"); 
     printf("9) Exit"); 

     } 

void getUserSelection(int *number){ 

     printf("\nSelect an option: "); 
     scanf("%d",number); 

     } 

void performOperation(int option){ 

     switch(option){ 
        case 1: 
          addNodeAtBeginning(); 
          break; 

        case 2: 
          addNodeAtEnd(); 
          break; 

        case 3: 
          addAtuserSpecificLocation(); 
          break; 

        case 4: 
          deleteFirstNode(); 
          break; 

        case 5: 
          deleteLastNode(); 
          break; 

        case 6: 
          deleteFromAspecificPosition(); 
          break; 

        case 7: 
          displayLinkedList(); 
          break; 

        case 8: 
          deleteEntireList(); 
          break; 

        case 9: 
          exit(0); 
          break; 

          default: 
            printf("\n\n********Invalid option**************\n\n"); 
            break; 



       } 



     } 



     void addNodeAtBeginning(void){ 

        struct node *tempNode=NULL; 
        if(NULL==head) { 

            head= createNode(); 
            }else{ 
              tempNode=createNode(); 
              tempNode->next=head; 
              head=tempNode; 


              } 


          }  


    void addNodeAtEnd(){ 
       struct node*tempNode=NULL; 

        if(NULL==head) { 
            head=createNode(); 
            }else{ 
             tempNode=head; 
             while(NULL!=tempNode->next){ 
                tempNode=tempNode->next;    

                    } 

                    tempNode->next=createNode(); 



             } 

       }    

    struct node* createNode(){ 
      struct node *tempNode; 

      tempNode= (struct node*)malloc(sizeof(struct node)); 
      getDataFromUser(&tempNode->data); 
      tempNode->next=NULL; 
      return tempNode; 

      } 

void displayLinkedList(){ 
        struct node *tempNode; 
        printf("\n\n********************LINKED_LIST_DOUBLY*******************************\n\n\n"); 

        tempNode=head; 

        printf("[head]-->"); 
        while(NULL!=tempNode->next){ 

              printf("[%c]", tempNode-> data); 
              printf("--->"); 
              tempNode=tempNode->next;  


        } 
        printf("[%c]", tempNode->data); 
        printf("-->[X]"); 
        printf("\n\n********************LINKED_LIST_DOUBLY*******************************\n\n\n"); 


        } 


void getDataFromUser(char * data){ 

       fflush(stdin); 
       printf("Enter data: "); 
       scanf("%c",data); 

        } 

void addAtuserSpecificLocation(void){ 

    int location; 
    struct node *tempNode=NULL; 
    struct node *tempUserNode=NULL; 
    tempNode=head; 
    location=getLocationFromUser(); 

    int i; 
    for(i=1;i<location-1;i++){ 
      tempNode=tempNode->next; 

      } 

    tempUserNode=createNode(); 
    tempUserNode->next=tempNode->next; 
    tempNode->next=tempUserNode; 

    } 

int getLocationFromUser(void){ 
    int location; 
    int linkedListLength; 
    linkedListLength=getLengthOfLinkedList(); 
    while(location<0||location>linkedListLength){ 
    printf("\n\nEnter a valid location: "); 
    scanf("%d",&location); 
    } 

    return location; 



} 

int getLengthOfLinkedList(){ 
    struct node *temp; 
    int length=1; 
    if(NULL==head){ 
        printf("\n\nLinked list is empty cannot perform operation\n\n"); 
        }else{ 
        temp=head; 


    while(temp->next!=NULL){ 
        length++; 
        temp=temp->next;  
          } 
          } 
    return length; 


    } 

    void deleteFirstNode(void){ 

     struct node *tempNode=NULL; 

     if(NULL!=head){ 
         tempNode=head; 
         head=head->next; 
         free(tempNode); 

         }else{ 

          printf("\n\nThere is no node to delete\n\n"); 

          } 

     } 

void deleteLastNode(void){ 

    struct node *tempNode; 

    if(NULL!=head){ 
       tempNode=head; 

       while(NULL!=tempNode->next){ 
             tempNode=tempNode->next; 
              } 

              free(tempNode); 


        }else{ 

          printf("\n\nThere is no node to delete\n\n"); 
          } 


    } 

    void deleteFromAspecificPosition(void){ 

    int location; 
    struct node *tempNode; 

    if(NULL!=head){ 
       tempNode=head; 
        location = getLocationFromUser(); 
        int listIterator=0; 
        for(listIterator=0; listIterator<location-1;listIterator++){ 
          tempNode=tempNode->next; 

            } 

            free(tempNode); 

            } 
} 

void deleteEntireList(void){ 

     struct node* tempNode; 
     struct node* tempNode2; 
     if(NULL==head){ 
        printf("\n\nList is already empty\n\n"); 


        }else{ 
          tempNode=head; 

          while(tempNode->next!=NULL){ 
           tempNode2=tempNode->next; 
           free(tempNode); 
           tempNode=tempNode->next; 

               } 
               free(tempNode2); 
               head=NULL; 
          printf("\n\nList Deleted\n\n"); 

          } 


     } 
+0

非常感謝你 – stev

+0

:)不客氣 –