代码之家  ›  专栏  ›  技术社区  ›  NiRvanA

无法在C中的链表中添加值[重复]

  •  1
  • NiRvanA  · 技术社区  · 4 年前

    前言 :目标是提示用户输入,将每个元素(输入行)添加到链表中。

    我一直在使用一些示例代码 Learn-C.org ,显示了一个链表示例。 我修改了代码,使其接受“字符串”而不是整数。

    我的 插入 功能如下:

    void push(node_t * head, char *data) {
        node_t * current = head;
    
        if(head == NULL) {
          printf("First element ever!\n");
        }
        else if(current->data == NULL) {
          current->data = data;
          current->next = NULL;
    
        }
        else {
          while (current->next != NULL) {
            current = current->next;
            }
          current->next = malloc(sizeof(node_t));
          current->next->data = data;
          current->next->next = NULL;
       }
    }
    

    现在,在MAIN中,我按如下方式启动列表:

    node_t * test_list = malloc(sizeof(node_t));
    

    添加元素是通过以下方式完成的:

      push(test_list, "FOO");
      push(test_list, "FEE");
      push(test_list, "FAA");
    

    打印列表时,使用 print_list(test_list) ,我得到以下输出:

    FOO
    FEE
    FAA
    

    问题

    然而,我随后添加了一个while循环,提示用户输入并将其添加到链表中。

    char command[120];
    int counter = 0;
    while(counter < 3) {
        printf("Enter element: ");
        fgets((void *)command, sizeof(command), stdin);
        push(test_list, command);   //Insert
        counter++;
    }
    

    但是,这并不会将每个元素添加到链接列表中。相反,它将LAST元素添加到列表中三次。

    例如,当提供:

    Enter element: Argentina
    Enter element: Mexico
    Enter element: Sweden
    

    列表打印为:

    FOO
    FEE
    FAA
    Sweden
    Sweden
    Sweden
    

    编辑 (新增打印功能)

    我的 打印 功能如下:

    void print_list(node_t * head) {
        node_t * current = head;
    
        printf("**** Printing list ****\n");
        while (current != NULL) {
            printf("%s\n", current->data);
            current = current->next;
        }
    }
    

    我错过了什么,或者:我该如何解决这个问题?任何帮助都将不胜感激。

    0 回复  |  直到 9 年前
        1
  •  2
  •   rohit89    9 年前

    使用 strdup 返回堆上分配的字符串的副本。

    strdup()函数返回一个指向新字符串的指针,该字符串是字符串s的副本。新字符串的内存是通过malloc(3)获得的,可以通过free(3)释放。

    node_t *test_list = malloc(sizeof(node_t));
    test_list->next = NULL;
    test_list->data = NULL;
    while(counter < 3) {
      printf("Enter element: ");
      fgets((void *)command, sizeof(command), stdin);
      push(test_list, strdup(command));   //Insert
      counter++;
    }
    
        2
  •  0
  •   Sami Kuhmonen    9 年前

    你有一个数组 command 容量为120。您可以使用它来读取值。这没问题。

    然后,您发送一个指向要存储的数组的指针。它被储存起来了,一切都很好。

    下次读取输入时,您将其读取到同一个数组中,并为该数组提供了一个要存储的指针。因此,您正在更改指针指向的内存内容。这是不正常的。

    您需要为每个字符串分配单独的内存区域并处理它们的释放。 strdup 是获取包含用户输入内容的新存储块的最简单方法。

    但请记住,当你不再需要内存时,你真的必须释放内存。在这种情况下,您可能永远不会删除任何字符串,但当您这样做时,您不能只删除元素,还必须释放字符串使用的内存。

        3
  •  0
  •   Nayan Khant    8 年前

    current->data = data; 在这里,您只复制指针地址而不是数据,在该地址(“命令”的地址)上,最后一个数据(“隐藏”)将可用。 你应该使用 strcpy(current->data,data) 复制数据。