我有以下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函数?
答案 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;
当你在新列表中创建第一个节点时,没有问题,newList
和tail
都指向该节点。现在想想在第二个节点创建第二个节点时会发生什么。新名单 -
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。现在尾巴并没有指向任何一块商品。你丢失了已经商品化的内存的指针
所以实际上没有在这里制作链接列表