我在C中为“单一链接列表”编写代码。在这段代码中,我想在列表的末尾插入元素。它汇编得很好。但是在运行时期间,预期的输出不会到来。我使用gcc
作为编译器。每当我在终点站做./a.out
时,它就被绞死了。
这是代码:
#include<stdio.h>
#include<stdlib.h>
struct list
{
int node;
struct list *next;
};
void insert(struct list *, int);
void print(struct list *);
int main()
{
struct list *mylist;
insert(mylist, 10);
insert(mylist, 20);
insert(mylist, 30);
insert(mylist, 40);
insert(mylist, 50);
insert(mylist, 60);
print(mylist);
return 0;
}
void print(struct list *head)
{
if(head==NULL)
return;
else
{
while(head->next!=NULL)
{
printf("%d\t",head->node);
head=head->next;
}
}
}
void insert(struct list *head, int value)
{
struct list *new_node;
new_node = (struct list *)malloc(sizeof(struct list));
//node Creation
new_node->node=value;
new_node->next=NULL;
//Adding Node to list
if(head==NULL)
{
head=new_node;
}
else
{
while(head->next!=NULL);
{
head=head->next;
}
head->next=new_node;
}
}
此处insert()
是在mylist
linklist和print()
中插入元素的函数,它是打印链接列表中所有值的函数。请帮忙。我无法理解我犯了什么错误。
答案 0 :(得分:5)
我建议再做一次更改,即函数的原型应该像
void insert(struct list **, int);
void print(struct list **);
并且应该相应地改变身体。因为你在insert中已经完成了新的内存分配,所以你不应该通过值进行传递,而应该通过地址传递,然后才能按预期工作。
此外,在打印功能中,循环终止应该是 while(* head!= NULL)而不是while((* head) - &gt; next!= NULL)否则它会跳过最后一个节点。
在第一次调用insert函数并且tmp指针应该在最后传递给print函数时,你应该将第一个节点存储到tmp指针中。在您的代码中,您将指针传递给错误的最后一个节点。所以,应该是这样的。
int main()
{
struct list *mylist=NULL, *tmp = NULL;
insert(&mylist, 10);
tmp = mylist; /* here */
insert(&mylist, 20);
insert(&mylist, 30);
insert(&mylist, 40);
insert(&mylist, 50);
insert(&mylist, 60);
/* At this point mylist is pointing to last node, so pass tmp which stores the first node */
print(&tmp);
return 0;
}
答案 1 :(得分:4)
问题在于以下行,
while(head->next!=NULL);
应该是,
while(head->next!=NULL)
删除分号。
答案 2 :(得分:2)
有一些错误:
1)您的代码编写者struct list *head;
。你知道在C和C ++中这样的变量没有被初始化吗?你不能指望它是NULL
,除非它在全球范围内;在使用之前,必须始终初始化局部变量。
2)你的插入函数按值接收head
所以当它改变它时(在列表为空的情况下)它只修改它的本地副本而不是head
变量main
}。您必须将head
作为struct list **
传递,或者必须将新的head
值返回给main。在C ++中,另一种方法是将其作为list *&
(对指针的引用)传递。
3)你的while
循环在身体前面有一个额外的分号,因此它是一个空循环,身体部分将始终执行(无论条件是什么)并且恰好一次,因为它只是一个嵌套的{ {1}}阻止。
答案 3 :(得分:1)
这是一个很好的无限循环。如果您使用调试器,您可以自己找到它^^。
while(head->next!=NULL);
您还需要在主要功能中初始化列表。
struct list *mylist = NULL;
你还需要将你的insert参数更改为一个双指针(如果只传递它的指针,则不会发生主头列表值更改,因为它只是复制地址值)
void print(struct list *head)
{
while(head!=NULL)
{
printf("%d\t",head->node);
head=head->next;
}
}
void insert(struct list **head, int value)
{
struct list *new_node;
new_node = (struct list *)malloc(sizeof(struct list));
//node Creation
new_node->node=value;
new_node->next=NULL;
//Get the end of the list
while((*head)->next!=NULL)
{
(*head)=(*head)->next;
}
// Add the node at the end of the list
(*head)->next=new_node;
}
int main()
{
struct list *mylist = NULL;
insert(&mylist, 10);
insert(&mylist, 20);
insert(&mylist, 30);
insert(&mylist, 40);
insert(&mylist, 50);
insert(&mylist, 60);
print(mylist);
return 0;
}
答案 4 :(得分:1)
虽然它不会立即解决您的问题,但请注意,您的应用程序中未释放动态分配的内存:程序泄漏。
强烈建议添加另一个函数destroy
:
void destroy(list * head)
{
while(head != NULL)
{
struct list * tmp = head->next;
free(head);
head = tmp;
}
}
这是一个完整的工作示例,不泄漏:http://ideone.com/y2Fl7i