【问题标题】:Errors in insert at back for linked list链表在后面插入错误
【发布时间】:2020-07-21 20:29:48
【问题描述】:

我正在尝试为链表构建基本操作库,但我遇到了函数push_back() 的问题:将数据推送到链表的末尾。 这是我的源代码:

node* push_back(node *dir, item datain)
{
    node *newnode = (node *)malloc(sizeof(node));
    newnode->data = datain;
    newnode->next = NULL;
    if (dir == NULL)
    {
        dir = newnode;
    }
    else
    {
        while (dir->next != NULL)
            dir = dir->next;
        dir->next = newnode;
    }
    return dir;
}
void printlist(node *dir)
{
    printf("%-50s%-50s%-20s\n", "Name", "Email", "Phone number");
    while (dir != NULL)
    {
        item temp = dir->data;
        printf("%-50s%-50s%-20s\n", temp.name, temp.email, temp.phone);
        dir = dir->next;
    }
}
int main()
{
    node *dir = (node *) malloc(sizeof(dir));
    dir = NULL;
    int i = 0;
    while(i<3)
    {
        item temp = userdata();
        dir = push_back(dir, temp);
        i++;
    }
    printlist(dir);
    freelist(dir);
    return 0;
}

我的问题:如果我只插入 2 条记录(每条记录都有姓名、电子邮件和电话号码),那就没问题了。但是,如果有超过 2 条记录,当我打印插入的全部记录时,它只会打印出最新的两条记录。我在一些网站上检查了我的代码,但我发现它们与我的完全不同。 例如:

输入:

输入姓名:乔伊

输入邮箱:Joey@gmail.com

输入电话号码:0235632514

输入姓名:马修

输入电子邮件:Mathew@gmail.com

输入电话号码:012502252

输入姓名:韦利

输入邮箱:Waley@gmail.com

输入电话号码:036625125

输出:

姓名 电子邮件 电话号码

Mathew Mathew@gmail.com 012502252

Waley Waley@gmail.com 036625125

【问题讨论】:

  • node *dir = (node *) malloc(sizeof(dir)); 看起来不对。如果有的话,它应该是sizeof(*dir)。尽管无论如何您都会在下一行泄漏该内存,但这完全没有意义
  • @UnholySheep 它并没有解决我说的问题。实际上我的语法仍然是正确的,但它可能会令人困惑
  • 我怀疑问题是dir = push_back(dir, temp); - 你用函数返回的指针“覆盖”指针,它始终是列表的倒数第二个节点
  • @UnholySheep 我同意你的观点,但我发现这里的错误很难找出,因为它与 Internet 上的代码几乎相同
  • 将您的代码与您在 Internet 上找到的代码进行比较是找出问题的不好方法。您需要使用调试器单步调试代码和/或分析您在纸上所做的工作

标签: c linked-list dynamic-memory-allocation


【解决方案1】:

第一个问题:

 node *dir = (node *) malloc(sizeof(dir));
 dir = NULL;

所以你有一个内存泄漏,因为你失去了分配,只是这样做

node *dir = NULL;

第二个问题push_back 这样做会返回列表的最后一个元素

dir = push_back(dir, temp);

dir 现在指向最后一个元素,你失去了列表的头部,所以除了最后一个元素之外的所有元素

一种方法是修改 push_back 以返回列表的(新)头部:

node* push_back(node * head, item datain)
{
    node *newnode = (node *)malloc(sizeof(node));

    newnode->data = datain;
    newnode->next = NULL;

    if (head == NULL)
        return newnode;

    node * dir = head;

    while (dir->next != NULL)
       dir = dir->next;
    dir->next = newnode;

    return head;
}

但这假设调用者总是做类似 dir = push_back(dir, temp);

另一种方法是使用双指针:

void push_back(node ** head, item datain)
{
    node *newnode = (node *)malloc(sizeof(node));

    newnode->data = datain;
    newnode->next = NULL;

    if (*head == NULL)
        *head = newnode;
    else {
      node * dir = *head;

      while (dir->next != NULL)
         dir = dir->next;
      dir->next = newnode;
    }
}

而调用者只需执行 push_back(&dir, temp); 而不会冒忘记分配的风险

【讨论】:

  • 至于第一个问题,我仍然不知道为什么会出错,因为dir = NULL这里只是通知它是空列表。第二个问题,我认为你的权利,但我不知道如何返回列表的头部。你能告诉我怎么做吗?
  • 谢谢,我得到了预期的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-07
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
相关资源
最近更新 更多