簡體   English   中英

復制鏈表-導致程序崩潰

[英]Copying a linked list- crashes the program

我有以下C代碼復制鏈接列表(取自斯坦福CS庫文件):

struct Node* CopyList(struct Node* head)
{
       struct Node* current = head;
       struct Node* newList= NULL;
       struct Node* tail= NULL;

       while (current !=NULL)
       {
             if(newList==NULL)
             {
                 newList=malloc(sizeof(struct Node));
                 newList->data=current->data;
                 newList->next=NULL;
                 tail= newList;
             }
             else
             {
                 tail= malloc(sizeof(struct Node));
                 tail= tail->next;
                 tail->data=current->data;
                 tail->next = NULL;
             }
             current= current->next;
       }
       return(newList);
}

我將以下內容作為主要功能的一部分:

struct Node* head = NULL;
for (i=3; i >=1;i--)   //insert 3 elements into the linked list
   {                   //push inserts elements in the front
       Push(&head,i); 
   } //now a linked list 1->2->3->NULL is formed

struct Node* newlst= CopyList(head); // copies contents into a new linked list

我正在使用Bloodshed Dev C ++編譯代碼。 我沒有得到任何編譯錯誤,但是當我運行它時,它崩潰了。 這可能是什么問題? 我是否將正確的參數傳遞給CopyList函數?

您的問題就在這里,在else

tail = malloc (sizeof (struct Node));
tail = tail->next;
tail->data = current->data;
tail->next = NULL;

您正在分配一個節點,並設置tail指向它(在第一行中)。 然后,您使用的tail ,仿佛這是舊的尾巴。 具體來說,第二行將為您提供流氓指針(因為您尚未使用有效的指針初始化新節點),當您嘗試取消引用它時,它可能會崩潰。

您需要類似:

// First, set up the new node.

newList = malloc (sizeof (struct Node));
newList->data = current->data;
newList->next = NULL;

// Then, adjust the tail pointers.

tail->next = newList;
tail = newList;

實際上,回顧一下您的代碼,您可能想要的是:

tail->next = malloc (sizeof (struct Node)); // use tail->next, not tail.
tail = tail->next;
tail->data = current->data;
tail->next = NULL;

達到相同的結果。

我想我應該提到的是,如果內存不足,您確實應該檢查malloc的返回值。 您可以使用以下方法執行此操作:

tail->next = malloc (sizeof (struct Node)); // use tail->next, not tail.
if (tail->next == NULL) {
    // do something here for recovery.
    return;
}
// Only continue here if the allocation worked.
tail = tail->next;
tail->data = current->data;
tail->next = NULL;

沒有這樣的檢查,當內存不足時,您將崩潰。

您正在為tail分配內存,它應該是tail-> next。 沒有這個,您將失去先前的指針。 修改后的代碼

struct Node* CopyList(struct Node* head) 
{        
    //.... same as before

    while (current !=NULL)        
    {              
        if(newList==NULL) 
        {              
            //.... same as before
         }              
         else
         {                   
            tail->next = malloc(sizeof(struct Node));                   
            tail= tail->next;                   
            tail->data=current->data;                   
            tail->next = NULL;                   
          }              

          current= current->next;        
     }        

     return(newList); 
}

sh

如果它只是死了,那通常是訪問無效指針的一種方法。 最有可能是空指針。

考慮這條線-

tail = tail->next;

當您在新列表中創建第一個節點時,就可以了, newListtail指向該節點。現在,考慮在新列表中創建第二個節點時會發生什么-

tail = malloc(sizeof(struct Node));    // tail points to the new node
tail = tail->next;                     // You are assigning new node's next to tail, but
                                       // did you initialize next to anything?

因此next未初始化為任何東西,而您將其分配給tail ,因此tail現在包含垃圾。 在接下來的兩行中給它分配一些值時,您的程序肯定會崩潰。

除了將新節點分配給tail ,您還需要將其分配給tail的next節點-

tail->next = (struct Node *) malloc(sizeof(struct Node) * 1);

這是您的問題:

              tail= malloc(sizeof(struct Node));
              tail= tail->next;

尾部指向內存的統一區域。 所以tail-> next可能是任何東西。

嘗試

              tail->next= malloc(sizeof(struct Node));
              tail= tail->next;

在else塊中,您已編寫此代碼

             tail= malloc(sizeof(struct Node));
             tail= tail->next;
             tail->data=current->data;
             tail->next = NULL;

第1行:tail指向一個節點,並且該節點的所有成員都具有值,因為tail尚未初始化。

Line2:將具有垃圾值的tail-> next分配給tail。 現在,尾巴不指向任何mall腳的記憶。 而您失去了已經陷入困境的記憶的指針

所以實際上鏈接列表不在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM