C即使分配了内存,修改链表的程序也会导致分段错误

时间:2018-03-02 04:48:06

标签: c linked-list segmentation-fault

对于我的程序,我必须从一个空的链表开始,并能够对它执行各种操作(即添加到开头,添加到结尾等) 我的列表结构如下

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);
}

3 个答案:

答案 0 :(得分:0)

首先:

val

这会将用户键入的值存储到val指定的地址中,此时未定义。您希望将其存储在地址 <{em> scanf("%d", &val);

应该是:

  else
  {
    struct node *insertnode = (struct node*)malloc(sizeof(struct node));
    insertnode->num = val;
    insertnode->next = llist;
    llist = insertnode;
  }

你的&#34;否则&#34;条款需要做很多工作。它可以简化为:

llist

现在让我们清理整个功能。

第一步。只需在程序启动时将created初始化为NULL并删除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; } ,即创建一个新节点并将其插入头部就是这样:

makecert -r -pe -n "CN=Sam-DPS.azure-devices-provisioning.net" -cy authority -sky signature -sv Sam-DPS.pvk Sam-DPS.cer

makecert -pe -n "CN=hl1234" -cy end -sky signature -ic Sam-DPS.cer -iv Sam-DPS.pvk -sv hl1234.pvk hl1234.cer

答案 1 :(得分:0)

检查scanf()您需要&val代替val

对于其他部分,你为什么要释放llist的记忆?您可以直接检查列表是否为null,而不是检查创建的变量。 在这种情况下,我建议使用Head节点。然后,您可以轻松地分配当前节点的next以指向先前添加的节点,并将头节点的next分配给当前添加的节点。

答案 2 :(得分:0)

有很多问题。除了selbie(第一编辑)所说的其他几个: -

  1. 您对如何解决问题的理解存在问题。例如,你已经写了

    '+/'

    这是内存泄漏。为什么需要这个?因为您想添加新节点。但你没有正确使用它。

  2. 代码的设计并不是那么好我会说 - temp = (struct node*)malloc(sizeof(struct node)); temp = llist; 在循环外部分配内存并在内部进行修改。为什么不在需要的地方分配内存?你可以改变它。

  3. 所以你可以修改它:-(这会在列表的头部添加新的节点)

    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的返回值。完成整个清单后,请释放这些记忆。

  4. 简单地说malloc函数就像是

    showList