【问题标题】:Why does this linked list give junk numbers?为什么这个链表会给出垃圾号码?
【发布时间】:2021-04-07 16:10:28
【问题描述】:

我正在尝试编写一个程序来创建一个链接列表,当用户输入一个数字时更新该链接列表,并在用户希望终止列表时打印输入的数字。

该程序似乎返回随机数。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <cs50.h>

int main(void)
{
    typedef struct node
    {
        int number;
        struct node *next;
    }
    node;
    int i = 0;
    int x;
    char v;
    node *list = NULL;
    node* temp = NULL;
    x = get_int("Enter number: \n");
    list = malloc(sizeof(node));
    list -> number = x;
    list -> next = NULL;
    while(i == 0)
    {
        x = get_int("Enter number: \n");
        node *n = malloc(sizeof(node));
        temp = malloc(sizeof(node));
        n -> number = x;
        n -> next = NULL;
        for(temp = list; temp->next != NULL; temp = temp -> next)
        {
            i = 0;
        }
        temp->next = n;
        free(n);
        list = temp;
        v = get_char("Proceed? :\n");
        if(v == 'n')
        {
            break;
        }
        else if(v == 'y')
        {
            continue;
        }
        else return 1;
    }
    for(node *temp1 = list; temp1 != NULL; temp1 = temp1 -> next)
    {
        printf("%d\n",temp1 -> number);
    }
}
    

cs50 头文件允许使用get_ 函数,而不是使用printfscanf 的组合。

我想知道这里出了什么问题。

【问题讨论】:

  • temp = malloc(sizeof(node)); 会导致内存泄漏,不需要
  • 仅供参考,您似乎想要在构建链接列表时执行所谓的 前向链接,从而保留原始顺序(而不是将其构建为 LIFO结构,例如堆栈)。它并不像你想象的那么复杂。 see here.

标签: c list data-structures linked-list cs50


【解决方案1】:

代码有几个问题

  1. temp = malloc(sizeof(node)); 会导致内存泄漏,因为你在几行之后用list 重写了它
    Sol: 实际上你不需要为temp 分配内存,因为它已被使用仅用于迭代您的列表。

  2. temp-&gt;next = n; free(n);free 在存储下一个节点后将使n 释放分配的内存,但您的temp-&gt;next 仍将指向已释放的内存,因此您的list 和访问它是非法的。
    索尔:
    (a) 不要使用free(n)
    (b) 你不需要这个 list = temp; ,因为你已经在末尾添加了节点,这样做 list = temp; 将从 list 中删除现有元素。

  3. else return 1; , Incase v 不是 ny 然后我们返回而不打印列表并释放分配的内存,你不希望这样。
    Sol: 更好的办法是打破这一点,打印listfree 内存。

  4. while(i == 0)
    您可以简单地使用 while(1) 并在您不想继续时正确中断。

【讨论】:

  • 如果使用free(n) 导致问题,我如何释放分配给n 的内存?
  • 什么问题?如果n 指向从malloc 或其他相关函数获得的有效内存,则不会有任何问题
  • (2) 你要我不要使用free(n)
  • 如果您使用free,您创建的新节点将不会附加到您的列表中。根据我的 commnets 更新代码后,您是否发现任何问题
  • 我刚刚评论了错误代码并跑到这里检查一个here
【解决方案2】:

我将备注答案作为 cmets 放在代码中:

while(i == 0) // advice : since i is always equals to 0, while (1) do the same job
{
    x = get_int("Enter number: \n");
    node *n = malloc(sizeof(node));
    temp = malloc(sizeof(node));  // warning : will lead to memory leak since this value is never used
    n -> number = x;
    n -> next = NULL;
    for(temp = list; temp->next != NULL; temp = temp -> next)
    {
        i = 0; // advice : not really usefull
    }
    temp->next = n;
    free(n); // ERROR : the new node is freed here so its memory may get garbage at any time
    list = temp; // ERROR : the begining of the linked list is lost here ; it now always points to the last new node
    v = get_char("Proceed? :\n");
    if(v == 'n')
    {
        break;
    }
    else if(v == 'y')
    {
        continue;
    }
    else return 1;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 2023-03-25
    • 2021-02-20
    • 1970-01-01
    • 2021-10-06
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多