对于我的程序,我必须从一个空的链表开始,并能够对它执行各种操作(即添加到开头,添加到结尾等)。我的列表结构如下
struct node {
int num;
struct node *next;
};
这是函数的开始,我已经分配空间并初始化列表,然后是while循环,其中case 1是添加到开始函数。对于此问题,可以忽略else部分。
printf("Who's ready to create and edit a linked list?\n");
printf("Note: The list is currently empty, please choose option 1.\n");
int choice, val, location, created;
struct node *llist;
llist = (struct node*)malloc(sizeof(struct node));
created =0;
while(choice != 8)
{
printf(" Operation Choices\n");
printf("1. Insert node at beginning\n");
printf("2. Insert node at end\n");
printf("3. Delete node from end\n");
printf("4. Delete node from beginning\n");
printf("5. Delete node from custom position\n");
printf("6. Insert node at custom position\n");
printf("7. Modify custom node\n");
printf("8. Exit\n");
scanf("%d", &choice);
switch(choice) {
case 1:
printf("Value to enter: \n");
scanf("%d", val);
if(created == 0)
{
llist->num=val;
llist->next = NULL;
created = 1;
}
else
{
struct node *temp;
temp = (struct node*)malloc(sizeof(struct node));
temp = llist;
free(llist);
llist = (struct node*)malloc(sizeof(struct node));
llist->num=val;
llist->next=temp;
free(temp);
showlist(llist);
}
break;
}
}
}
选项当前为'0',表示我没有向列表添加任何值,并且if部分正在执行。当我运行代码并尝试添加我的第一个值时,即使分配了内存,我仍然会遇到分段错误。我错过了什么?
知道为什么这个打印功能也不起作用?
void showlist(struct node *list)
{
do{
printf("%d->", list->num);
list = list->next;
}
while(list->next != NULL);
}
检查你的scanf()
你需要把&val
而不是val
。
对于其他部分,你为什么要释放llist
的记忆?您可以直接检查列表是否为null
,而不是检查创建的变量。在这种情况下,我建议使用Head
节点。然后,您可以轻松地将当前节点的next
指定为指向先前添加的节点,并将头节点的next
分配给当前添加的节点。
对于初学者:
scanf("%d", val);
这会将用户键入的值存储到val
指定的地址中,此时此位置未定义。您想将其存储在val
的地址中。
应该:
scanf("%d", &val);
而你的“其他”条款需要做很多工作。它可以简化为:
else
{
struct node *insertnode = (struct node*)malloc(sizeof(struct node));
insertnode->num = val;
insertnode->next = llist;
llist = insertnode;
}
现在让我们清理你的整个功能。
第一步。只需在程序启动时将llist
初始化为NULL并删除created
变量。
struct node *llist = NULL;
然后你的case 1
,即创建一个新节点并将其插入头部就是这样:
case 1:
{
/* create a new node and make it the new head of the list */
struct node* insertnode = (struct node*)malloc(sizeof(struct node));
printf("Value to enter: \n");
scanf("%d", &(insertnode->val));
insertnode->next = llist; /* next points to the existing head, which will be null on first call */
llist = insertnode; /* head now points to the new node*/
break;
}
有很多问题。除了selbie(第一编辑)说的还有其他几个: -
temp = (struct node*)malloc(sizeof(struct node));
temp = llist;
这是内存泄漏。为什么需要这个?因为您想添加新节点。但你没有正确使用它。llist
在循环外部分配了内存并且在内部进行了修改。为什么不在需要的地方分配内存?你可以改变它。 if(created == 0)
{
llist = malloc(sizeof *llist);
llist->num=val;
llist->next = NULL;
created = 1;
}
else
{
struct node *temp;
temp = malloc(sizeof *temp);
temp->num=val;
temp->next=llist;
llist = temp;
showlist(llist);
}
那些为malloc
铸造的人不需要。当然,你可以检查malloc
的返回值。完成整个列表后,释放这些记忆。showList
函数会是这样的
void showlist(struct node *list) {
while(list)
{
printf("%d->", list->num);
list = list->next;
}
}