复制链接列表会导致程序崩溃

时间:2011-08-05 03:41:07

标签: c data-structures linked-list

我有以下C代码来复制链表(取自Stanford CS Library文件):

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函数?

6 个答案:

答案 0 :(得分:3)

你的问题在于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;

如果没有这样的检查,当你内存不足时就会崩溃。

答案 1 :(得分:2)

你正在为尾部分配内存,它应该是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); 
}

词shash

答案 2 :(得分:0)

如果它刚刚死掉,那通常就是访问无效指针。很可能是空指针。

答案 3 :(得分:0)

考虑这一行 -

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 -

,而不是将新节点分配给next
tail->next = (struct Node *) malloc(sizeof(struct Node) * 1);

答案 4 :(得分:0)

这是你的问题:

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

尾部指向记忆的单位区域。所以tail-> next可能是任何东西。

尝试

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

答案 5 :(得分:0)

在else块中你已经编写了这段代码

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

第1行:tail指向一个节点,并且该节点的所有成员都具有值,因为tail尚未初始化。

Line2:tail-> next具有垃圾值被分配给tail。现在尾巴并没有指向任何一块商品。你丢失了已经商品化的内存的指针

所以实际上没有在这里制作链接列表