You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言链表相邻节点交换代码在VSCode中出现Segmentation Fault

链表相邻节点交换代码段错误分析与修复

你的代码在VSCode中触发段错误,核心原因是内存未初始化加上边界处理缺失,以下是具体问题和修复方案:

核心错误点

  • insert_end函数未初始化新节点的next指针:malloc分配的堆内存是未初始化的随机值,第一次插入节点时,new_node->next不是NULL。后续遍历链表时,temp->next会指向非法内存,触发段错误。在线编译器可能默认将堆内存清零,所以侥幸运行正常,但GCC等标准编译器不会做这个操作。
  • swap函数未处理空链表/单节点情况:如果传入的链表为空,(*head)->next会直接访问空指针,导致段错误。
  • main函数不符合C标准:标准C要求main函数返回类型为int,而非void。

修复后的代码

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

typedef struct node
{
    int val;
    struct node *next;
} node;

void insert_end(node **head, int d)
{
    node *new_node = (node *)malloc(sizeof(node));
    if (new_node == NULL) { // 增加malloc失败判断
        perror("malloc failed");
        exit(EXIT_FAILURE);
    }
    new_node->val = d;
    new_node->next = NULL; // 强制初始化next为NULL,从根源避免非法遍历
    if (*head == NULL)
        *head = new_node;
    else
    {
        node *temp = *head;
        while (temp->next != NULL)
            temp = temp->next;
        temp->next = new_node;
    }
}

node *swap(node **head)
{
    if (*head == NULL || (*head)->next == NULL) { // 处理空链表或单节点的边界情况
        return *head;
    }
    node *temp = (node *)malloc(sizeof(node));
    if (temp == NULL) {
        perror("malloc failed");
        exit(EXIT_FAILURE);
    }
    temp->next = *head;
    node *start = (*head)->next;
    while (temp->next != NULL && temp->next->next != NULL)
    {
        node *ptr1 = temp->next;
        node *ptr2 = temp->next->next;
        temp->next = ptr2;
        ptr1->next = ptr2->next;
        ptr2->next = ptr1;
        temp = ptr1;
    }
    free(temp); // 释放临时节点,避免内存泄漏
    return start;
}

void disp(node *head)
{
    while (head != NULL)
    {
        printf("%d\n", head->val);
        head = head->next;
    }
}

int main() // 改为标准int返回类型
{
    int arr[] = { 1, 2, 3 };
    int size = sizeof(arr) / sizeof(arr[0]);
    node *head = NULL;

    for (int i = 0; i < size; i++)
    {
        insert_end(&head, arr[i]);
    }

    node *ptr = swap(&head);
    disp(ptr);
    
    // 释放链表内存,避免内存泄漏
    node *temp;
    while (ptr != NULL) {
        temp = ptr;
        ptr = ptr->next;
        free(temp);
    }
    return 0;
}

关键修复说明

  1. 强制初始化新节点的next指针:创建新节点后立即将new_node->next设为NULL,确保链表尾节点始终合法,彻底避免遍历到非法内存。
  2. 增加malloc失败检查:malloc可能分配失败返回NULL,添加判断可以提前终止程序,避免后续空指针访问。
  3. swap函数边界处理:先判断链表是否为空或只有一个节点,直接返回原链表,避免空指针访问。
  4. 释放临时节点:swap中创建的temp节点用完后必须free,否则会造成内存泄漏。
  5. 修正main函数:改为标准的int main()并添加return 0,符合C语言规范。
  6. 添加链表内存释放:程序结束前遍历释放所有节点,养成良好的内存管理习惯。

内容的提问来源于stack exchange,提问作者Ankit Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:42:50