我找不到我的链表的错误(为啥我的头指针在移动?)

Posted

技术标签:

【中文标题】我找不到我的链表的错误(为啥我的头指针在移动?)【英文标题】:I cant find the error of my linked list( why is my head pointer moving?)我找不到我的链表的错误(为什么我的头指针在移动?) 【发布时间】:2022-01-21 03:55:28 【问题描述】:

我已经尝试了很多次来设置我的头指针指向第一个节点。首先(在空列表中)它正确地指向第一个节点。但是在第一个循环之后,头指针指向链接的新节点。其实现在我也很不确定我的整个代码。

int main(void)
struct library *head = NULL; //set the head pointer to NULL
int option;
printf("Enter the number:");


while((option = getchar())!= 9)
switch(option)
case '1':
    
    char title[1000];
    char author[1000];
    char subject[1000];
    printf("Enter title of the book you want to add:");
    scanf("%s",title);
    printf("Enter author of the book you want to add:");
    scanf("%s",author);
    printf("Enter subject of the book you want to add:");
    scanf("%s",subject);
    add_book(title,author,subject,&head);
    printf("successful! and head pointer is pointing to %s\n",head->collection.title);
    break;
    
  



void add_book(char title[],char author[],char subject[], struct library ** head)
struct library *current;
struct library *newnode = malloc(sizeof(struct library));
newnode->collection.title = title;
newnode->collection.author = author;
newnode->collection.subject = subject;      // assigning value inside newnode
newnode->num_books = 0;
newnode->next = NULL;                       // assign NULL value to the end of newnod

//when the head is NULL which means when the list is empty
if(*head == NULL)

    current = newnode;
    *head = current;

    return;


else

    current = *head;                //assign the first node to current pointer
    //find the last node of the list
    while(current->next != NULL)
    
        current = current->next;
    
    current->next = newnode;                    // link the last node to new node
    return;


这是这个结构

struct book 
char* title;
char* author;
char* subject;
;

struct library 
struct book collection;
int num_books;
struct library* next;
;

【问题讨论】:

为你的结构推荐 typedef,让阅读更容易 ex.) typedef struct library library = strdup(title) 等。您的本地 char 数组将无法返回。 您的 main 函数缺少右大括号 ()。请注意发布您的Minimal, Reproducible Example 的准确副本 - 最好带有适当的缩进。 【参考方案1】:

char title[1000];char author[1000];char subject[1000]; 的 lifetime 在执行到达 block 内部 case '1': /* ... */ 的末尾时结束。一旦发生这种情况,在add_book 中分配的指针就会变成dangling pointers - 指向无效的内存。

要解决这个问题,您必须确保字符串的生命周期与包含它们的结构的生命周期相匹配。这可以通过在结构本身中分配足够的空间来完成

struct book 
    char title[1000];
    /* etc. */
;

或通过为每个字符串的副本动态分配足够的空间。在任何情况下,您都必须将字符串复制到此内存 (man 3 strcpy)。

如果它在您的系统上可用,man 3 strdup 会同时执行第二种形式的两个步骤。否则与strcpy(malloc(strlen(source_string) + 1), source_string);大致相同。

还请注意,scanf 说明符 %s 在没有字段宽度说明符(例如,char buffer[1000]; scanf("%999s", buffer);)的情况下使用时与 dangerous as gets 一样,因为它可能会溢出您的缓冲区。


一个示例程序。逐个输入字符串,并以EOF CTRL+D 结束(Windows:CTRL+ZRETURN)。

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

struct link 
    char *string;
    /* alternatively: char string[512]; */
    struct link *next;
;

void add_link(struct link **root, const char *string) 
    struct link *node = calloc(1, sizeof *node);
    node->string = strdup(string);
    /* alternatively: strcpy(node->string, string) */

    if (*root) 
        struct link *tail = *root;

        while (tail->next)
            tail = tail->next;

        tail->next = node;
     else
        *root = node;


int main(void) 
    struct link *head = NULL;

    while (1) 
        char buffer[512];

        if (!fgets(buffer, sizeof buffer, stdin))
            break;

        /* remove newline */
        buffer[strcspn(buffer, "\n")] = '\0';

        add_link(&head, buffer);
    

    for (struct link *node = head, *next; node; node = next) 
        next = node->next;
        printf("STRING: %s\n", node->string);
        free(node->string);
        free(node);
    

注意:在实际程序中,您应该始终检查内存分配函数(malloccallocstrdup 等)的返回值,因为它们可能会失败。

【讨论】:

以上是关于我找不到我的链表的错误(为啥我的头指针在移动?)的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer-合并两个排序的链表

链表分割

链表的头插法和尾插法

删除链表的倒数第 N 个结点

Leetcode删除链表中的重复元素

Leetcode删除链表中的重复元素