2017-04-14 135 views
0

我有一些问题了解我的问题在我的程序中依赖的位置。我正在尝试发送每个相应的双向链接链表(垃圾列表和主列表)的头节点,然后返回垃圾桶的新头节点。C中的指针,导致段错误

我遇到的主要问题是,当我通过此函数将相应的节点添加到addTrash函数中的垃圾列表后,下次我试图使用主列表至少遍历它时,它段错误。

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

struct node { 
    int value; 
    struct node *next, *previous; 
}; 

struct node * modifyMainList(struct node *mainHead, int link2Delete){ 

    printf("inside modify list\n\n"); 
    struct node *curr, *temp; 
    temp = NULL; 
    curr = mainHead; 
    int i; 

    for (i = 0; i < link2Delete; i++){ 

     printf("%d\n", i); 
     curr = curr -> next; 
    } 

    if(curr -> previous == NULL){ 

     temp = curr; 
     curr = curr -> next; 

     curr -> previous = NULL; 

     temp -> next = NULL; 
     free(temp); 

     return mainHead; 
    }else{ 

     if((curr -> next == NULL) && (curr -> previous != NULL)){ 

      temp = curr; 
      curr = curr -> previous; 
      curr -> next = NULL; 

      temp -> previous = NULL; 
      free(temp); 

      return mainHead; 
     }else{ 

      temp = curr; 
      curr = curr -> previous; 
      curr -> next = curr -> next -> next; 
      curr = temp -> next; 
      curr -> previous = curr -> previous -> previous; 

      temp -> previous = NULL; 
      temp -> next = NULL; 
      free(temp); 

      return mainHead;    
     } 
    } 
} 

struct node * addTrash(struct node *trashHead, struct node *mainHead, int link2Delete){ 

    struct node *curr = mainHead, *trashCurr = NULL, *temp = NULL; 
    int i = 0; 

    for(i = 0; i < link2Delete; i++){ 

     curr = curr -> next; 
    } 

    printf("inside addTrash\n\n"); 
    if(trashHead == NULL){ 

     trashHead = curr; 
     trashHead -> previous = NULL; 
     trashHead -> next = NULL; 


     return trashHead; 

    }else{ 

     trashCurr = trashHead; 
     while(trashCurr -> next != NULL){ 

      trashCurr = trashCurr -> next; 
     } 

     trashCurr -> next = curr; 
     temp = curr; 
     temp -> previous = trashCurr; 
     temp -> next = NULL; 

     temp = NULL; 
     free(temp); 

     trashCurr = NULL; 
     free(trashCurr); 

     return trashHead; 

    } 
} 

//Traverses and prints out data from left to right 
void TraverseLeftRight(struct node *head){ 

    struct node *current; 
    current = head; 

    while(1){ 
     if(current != NULL){ 

      printf("Left to right output:   %d\n", current -> value); 
      current = current -> next; 
     }else{ 
      break; 
     }   
    } 
} 


//Traverses and prints out data from right to left 
void TraverseRightLeft(struct node *tail){ 

    struct node *current; 


    current = tail; 

    while(1){ 
     if(current != NULL){ 

      printf("Right to left output:   %d\n", current -> value); 
      current = current -> previous; 
     }else{ 
      break; 
     }   
    } 
} 


//inserts a node into the doubly linked linked-list 
struct node * insertIntoList(struct node *head, int value){ 

    int i; 
    struct node *current, *temp; 

    for(i = 0; i < value; i++){ 

     //Case 1: List empty 
     if (i == 0){ 

      //create node and assign all pointers and values 
      temp = (struct node *) malloc(sizeof(struct node)); 
      temp -> value = i; 
      temp -> next = NULL; 
      temp -> previous = NULL; 
      head = temp; 
      current = head; 
      printf("Input data:    %d\n", current -> value); 


     }else{ 

      //create node and assign pointers and values 
      temp = (struct node *) malloc(sizeof(struct node)); 
      temp -> value = i; 
      temp -> next = NULL; 

      //assign pointer of previous for temp to the current node 
      temp -> previous = current; 



      //change current node to the node that was just created 
      current -> next = temp; 
      current = current -> next; 
      printf("Input data:    %d\n", current -> value); 

     } 
    } 
    printf("\n"); 
    return head; 

} 

//frees the data on the doubly linked linked-list 

void Free(struct node *head){ 

    struct node *current, *temp; 

    current = head; 
    temp = head;  

    while(1){ 
     if(current != NULL){ 

      current = current -> next; 
      temp -> next = NULL; 
      temp -> previous = NULL; 
      temp -> value = 0; 
      free(temp); 
      temp = current; 

     }else{ 
      break; 
     }   
    } 


} 

int main(int argv, char **argc){ 

    struct node *head, *current, *tail, *temp, *trashHead; 
    int input, link2Delete = 0, size = 0, y = 0, number2Delete = 0, i; 
    head = NULL; 
    trashHead = NULL; 
    temp = NULL; 
    current = NULL; 
    tail = NULL; 

    //Check to see if there is the correct amount of arguments 
    if(argv < 2){ 
      printf("************************************************\n"); 
      printf("* You must include a number for size of list. *\n"); 
      printf("************************************************\n"); 

     //exit program 
     return 0; 

    }else{ 
     if(argv > 2){ 
      printf("*****************************************************************\n"); 
      printf("* You have entered too many arguments, arguments need to be 2. *\n"); 
      printf("*****************************************************************\n"); 

      //exit program 
      return 0; 

     }else{ 

      if(argv == 2){ 

       //convert string to int 
       input = atoi(argc[1]); 

       //create the doubly linked linked-list 
       head = insertIntoList(head, input); 



       //traverse and print values from left to right order 
       TraverseLeftRight(head); 

       //traverses the list to create the tail 
       current = head; 

       while(1){ 
        if(current != NULL){ 
         temp = current; 
         current = current -> next; 

        }else{ 
         break; 
        }   
       } 

       tail = temp; 

       printf("\n");    

       //traverse and print values from right to left order 
       TraverseRightLeft(tail); 

       //Generate the random numbers for the corresponding names to be deleted and the numbers of 
       //deletions made 
       srand(time(NULL)); 
       size = input; 
       number2Delete = rand() % size + 1; 

       printf("\n\nThis is the random number: %d\n", rand()); 
       printf("This is the nuber of nodes to be deleted: %d\n", number2Delete); 

       for(i = 0; i < number2Delete; i++){ 

        y = 0; 
        //Pick a random node for deletion 
        link2Delete = (rand() % size); 
        current = head; 
        while(current != NULL){     

         current = current -> next; 
         if(current != NULL){ 
          printf("this is node: %d\n", y); 
          y++; 
         } 
        } 

        printf("this is the node to be deleted: %d\n\n", link2Delete); 
        size--; 

        trashHead = addTrash(trashHead, head, link2Delete); 
        printf("this is the head of trash: %d\n\n", trashHead -> value); 
        head = modifyMainList(head, link2Delete);   
       } 

       Free(head); 
       return 0; 
      } 
     } 
    } 
} 
+0

'trashCurr = trashHead; (trashCurr!= NULL) trashCurr = trashCurr - > next; } trashCurr - > next = curr;':当while循环结束时,'trashCurr'为'NULL'。 – BLUEPIXY

+0

除了添加到垃圾清单之外,还需要重新配置主清单的链接。 – BLUEPIXY

+0

在跳过那个刚刚添加到垃圾桶中的节点时正确吗?如果是这样,我只是没有得到解决。只是试图确保垃圾清单的执行是正确的 –

回答

0

你在addTrash问题是在这里:

for(i = 0; i < link2Delete; i++){ 

您需要防止分配一个NULL指针trashHead,例如

for(i = 0; curr -> next && i < link2Delete; i++){ 

示例输出

$ ./bin/llmaintrash 5 
Input data:    0 
Input data:    1 
Input data:    2 
Input data:    3 
Input data:    4 
Input data:    5 

left to right output:  0 
left to right output:  1 
left to right output:  2 
left to right output:  3 
left to right output:  4 
left to right output:  5 

Right to left output:   5 
Right to left output:   4 
Right to left output:   3 
Right to left output:   2 
Right to left output:   1 
Right to left output:   0 


This is the random number: 1524010487 
This is the number of nodes to be deleted: 1 
this is node: 0 
this is node: 1 
this is node: 2 
this is node: 3 
this is node: 4 
this is the node to be deleted: 4 

this is the head of trash: 4 

作为附加的注释,你也可以显著缩短穿越功能,例如:

void traverseLeftRight (struct node *head) 
{ 
    for (struct node *current = head; current; current = current->next) 
     printf ("left to right output: %6d\n", current -> value); 
} 
+0

它不会因为implimentation而变为Null,因为link2Delete永远不会比使用我已经完成的设置的列表大小大,如果它变成Null,则是因为索引因为每个对应的不正确的指针处理而变为null节点。 –

+0

虽然这可能是一个问题,我非常积极,我做了添加正确的,它不应该改变原来的链表,因为我没有明确地尝试改变addTrash函数内。 –

+0

你的问题是分配'curr = curr - > next;','curr-> next'对于最终节点总是为NULL。 –

0
trashCurr = trashHead; 
    while(trashCurr != NULL){ 

     trashCurr = trashCurr -> next; 
    } 

    trashCurr -> next = curr; 

while循环末尾,trashCurr绝对是NULL。所以试图指定rtashCurr->next将会崩溃。也许你想:

trashCurr = trashHead; 
    while(trashCurr -> next != NULL){ 

     trashCurr = trashCurr -> next; 
    } 

    trashCurr -> next = curr; 
+0

是的,我注意到前一段时间,但忘了更新代码。接得好 :) –