【问题标题】:Segmentation fault while looping through a linked list循环通过链表时出现分段错误
【发布时间】:2022-01-13 00:47:30
【问题描述】:

我刚刚学习链表,我尝试创建一个函数,它循环遍历链表并打印出每个值。

但是,在我的 while 循环结束时,当我经过最后一个节点时,我遇到了分段错误。

虽然我可以通过将条件从 (temp != NULL) 设置为 (temp->next != NULL) 来消除分段错误,但仍然出现错误。 我会在这里得到一些帮助。

我提供了我得到错误的打印函数,但如果需要,我也可以提供完整的代码。

void printList(node_t *head){
    node_t *temp = head;

    if (temp != NULL) {
        while (temp->next != NULL) {
            int i = temp->value;
            printf("%d\n", i);
            temp = temp->next;
            
        }
    }
}

添加了更多代码。

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

struct node{
    int value;
    struct node *next;
};

typedef struct node node_t;

void printList(node_t *head){
    node_t *temp = head;

    if (temp != NULL) {
        while (temp->next != NULL) {
            int i = temp->value;
            printf("%d\n", i);
            temp = temp->next;

        }
    }

}

node_t *create_new_node(int value){
    node_t *next_pointer = malloc(sizeof(node_t));
    next_pointer->value = value;
    next_pointer->next = NULL;
    return next_pointer;
}

node_t *insert_at_head(node_t **head, node_t *new_node){
    new_node->next = *head;
    *head = new_node;
    return new_node;
}

int main(){
    node_t *tmp, *head;

    for(int i= 0; i<25; i++){
        tmp = create_new_node(i);
        insert_at_head(&head, tmp);
    }
    
    printList(head);
    
    return 0;
}

【问题讨论】:

  • 你的逻辑可以简化。请记住,如果条件为假,则不会执行 while 循环。
  • @avvocato 提供一个演示问题的最小完整程序。
  • 您的意思是因为 if 语句?我用它以防万一头部是空的。在此之前,我也使用了 while( temp != null) 来检查头部。
  • 使用该程序逻辑,您将错过最后一个元素。但是我不明白这怎么会出现段错误,除非列表的创建首先是虚假的,通常最后一个元素的下一个指针可能不指向任何地方。这是一个典型的初学者错误。您需要edit 并向我们展示minimal reproducible example 以获取更多信息。
  • 谢谢,起初我也会错过最后一项,但我不会。我编辑了更多代码,希望这会有所帮助! @Jabberwocky

标签: c struct linked-list segmentation-fault singly-linked-list


【解决方案1】:

程序的问题是你没有初始化指向头节点的指针

node_t *tmp, *head;

因此,随着新节点添加到头部,最后一个节点的数据成员 next 具有不确定的值。

你需要写

node_t *tmp, *head = NULL;

函数printList可以如下所示

void printList( const node_t *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d\n", head->value );
    }
}

函数create_new_node也应该定义如下

node_t * create_new_node( int value )
{
    node_t *next_pointer = malloc(sizeof(node_t));
    if ( next_pointer != NULL )
    {
        next_pointer->value = value;
        next_pointer->next = NULL;
    }

    return next_pointer;
}

【讨论】:

    【解决方案2】:

    初始化头部:

    node_t *tmp, *head=NULL;
    

    这样最终成为最后一个next 的内容定义明确,可以防止访问谁知道在哪里。

    然后我得到一个很好的反向输出(减去最后一个元素,第一次插入,0;见 Jabberwocky 的评论)。

    例如这里https://www.tutorialspoint.com/compile_c_online.php

    否则你会这样做:

    头->哦不
    头->1->哦不
    头->2->1->哦不
    ....

    这会触发你的输出函数,当它到达“OhNo”之前/之前,它指向谁知道在哪里。

    使用init是
    头->NULL
    头部->1->NULL
    头->2->1->NULL
    ...

    后者与您的输出函数完美配合。

    【讨论】:

    • 你忘了提到printList 错过了第一个元素。
    • 是的。我没有打扰,只想找到并解决段错误。但我提到并归功于你。谢谢。 @Jabberwocky
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 2014-03-23
    • 1970-01-01
    • 2015-05-18
    • 2017-11-24
    相关资源
    最近更新 更多