C即使分配了内存,修改链表的程序也会导致分段错误
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C即使分配了内存,修改链表的程序也会导致分段错误相关的知识,希望对你有一定的参考价值。
对于我的程序,我必须从一个空的链表开始,并能够对它执行各种操作(即添加到开头,添加到结尾等)。我的列表结构如下
struct node {
int num;
struct node *next;
};
这是函数的开始,我已经分配空间并初始化列表,然后是while循环,其中case 1是添加到开始函数。对于此问题,可以忽略else部分。
printf("Who's ready to create and edit a linked list?
");
printf("Note: The list is currently empty, please choose option 1.
");
int choice, val, location, created;
struct node *llist;
llist = (struct node*)malloc(sizeof(struct node));
created =0;
while(choice != 8)
{
printf(" Operation Choices
");
printf("1. Insert node at beginning
");
printf("2. Insert node at end
");
printf("3. Delete node from end
");
printf("4. Delete node from beginning
");
printf("5. Delete node from custom position
");
printf("6. Insert node at custom position
");
printf("7. Modify custom node
");
printf("8. Exit
");
scanf("%d", &choice);
switch(choice) {
case 1:
printf("Value to enter:
");
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:
");
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; } }
以上是关于C即使分配了内存,修改链表的程序也会导致分段错误的主要内容,如果未能解决你的问题,请参考以下文章