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

链表回文判断代码出现段错误,求排查与修复方案

链表回文判断程序的段错误排查与修复

问题概述

需要实现一个程序判断双向链表是否为回文结构,输入要求为:

  • 第一行:空格分隔的整数(链表元素)
  • 第二行:单个整数(链表长度)
    输出要求:是回文则输出Palindrome,否则输出Not Palindrome。

用户实现的创建链表和回文判断函数出现段错误,附带代码及编译器警告如下:

用户原代码

//The function for creating the nodes using array.
struct node* create(head){
    int n;
    printf("Enter the number of nodes in the linked list:");
    scanf("%d", &n);
    int arr[n];
    printf("Enter the character for each node spearated by spaces:");
    for(int i=0; i<n; i++){
        fscanf(stdin,"%d", &arr[i]);
    }
    for(int i=0;i<n;i++){
        struct node* temp = (struct node*)malloc(sizeof(struct node));
        temp->data = arr[i];
        temp->next = NULL;
        temp->prev=NULL;
        struct node* p;
        if(head==NULL){
            head=temp;
        }
        else{
            while (p->next!=NULL)
            {
                p=p->next;
            }
            p->next=temp;
            temp->prev=p;
        }
    }
}

//The function for checking palindrome

struct node* pallindrome(head){
    struct node* p = head;
    struct node* q = head;
    int count=0;
    while(q!=NULL){
        q=q->next;
        count++;
    }

    for(int i=0;i<(count/2);i++){
        if(p->data==q->data){
            p=p->next;
            q=q->prev;
            continue;
        }
        else{
            printf("Not Pallindrome");
            return;
        }
    }

    printf("Pallindrome");
}

编译器警告信息

pallindrome.c: In function 'create':
pallindrome.c:13:14: warning: type of 'head' defaults to 'int' [-Wimplicit-int]
 struct node* create(head){
              ^~~~~~
pallindrome.c:28:16: warning: comparison between pointer and integer
         if(head==NULL){
                ^~
pallindrome.c:29:17: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
             head=temp;
                 ^
pallindrome.c: In function 'pallindrome':
pallindrome.c:42:14: warning: type of 'head' defaults to 'int' [-Wimplicit-int]
 struct node* pallindrome(head){
              ^~~~~~~~~~~
pallindrome.c:43:22: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
     struct node* p = head;
                      ^~~~
pallindrome.c:44:22: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
     struct node* q = head;
                      ^~~~
pallindrome.c:59:13: warning: 'return' with no value, in function returning non-void
             return;
             ^~~~~~
pallindrome.c:42:14: note: declared here
 struct node* pallindrome(head){
              ^~~~~~~~~~~

错误分析与修复步骤

1. 函数参数类型缺失引发的类型错误

  • 问题:create和pallindrome函数的head参数未声明类型,C语言默认将其视为int类型,导致指针与整数的非法转换(如把struct node*赋值给int,用int初始化指针),直接引发地址访问错误。
  • 修复:给head参数添加正确的类型struct node*;create函数采用返回头指针的方式,避免二级指针的复杂操作。

2. 未初始化指针导致的段错误

  • 问题:create函数的else分支中,指针p未初始化就直接访问p->next,属于未定义行为,必然触发段错误。
  • 修复:改用tail指针记录链表尾部,直接追加新节点,无需每次遍历到尾部,既解决未初始化问题,又提升效率。

3. 函数未返回值导致的非法访问

  • 问题:create函数声明返回struct node*,但函数末尾无return语句,外部调用时会拿到垃圾值,访问链表时引发段错误;pallindrome函数声明返回struct node*,但实际无需返回值,return;语句会导致未定义行为。
  • 修复:create函数末尾添加return head;;将pallindrome函数的返回类型改为void,移除无意义的返回值。

4. 回文判断逻辑错误

  • 问题:遍历链表时q最终指向NULL,此时访问q->data或q->prev属于非法内存访问;计数逻辑也因q到NULL导致多算一个节点。
  • 修复:调整遍历逻辑,让q停在最后一个节点(而非NULL),再进行首尾对比。

5. 输入逻辑不符合题目要求

  • 问题:原create函数内部读取长度和元素,与题目“先输入元素、再输入长度”的要求不符,且耦合性高。
  • 修复:将输入逻辑移到main函数中,按照题目要求读取数据后,传入create函数创建链表。

修复后的完整代码

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

// 定义双向链表节点结构
struct node {
    int data;
    struct node* next;
    struct node* prev;
};

// 创建双向链表:接收元素数组和长度,返回头指针
struct node* create(int arr[], int n) {
    struct node* head = NULL;
    struct node* tail = NULL; // 用tail记录尾部,避免重复遍历

    for (int i = 0; i < n; i++) {
        struct node* temp = (struct node*)malloc(sizeof(struct node));
        temp->data = arr[i];
        temp->next = NULL;
        temp->prev = NULL;

        if (head == NULL) {
            head = temp;
            tail = temp;
        } else {
            tail->next = temp;
            temp->prev = tail;
            tail = temp; // 更新尾部指针
        }
    }
    return head;
}

// 判断链表是否为回文
void is_palindrome(struct node* head) {
    if (head == NULL) {
        printf("Palindrome\n");
        return;
    }

    struct node* p = head;
    struct node* q = head;

    // 移动q到最后一个节点
    while (q->next != NULL) {
        q = q->next;
    }

    int count = 0;
    struct node* temp = head;
    // 统计链表节点数
    while (temp != NULL) {
        count++;
        temp = temp->next;
    }

    // 首尾对比一半节点
    for (int i = 0; i < count / 2; i++) {
        if (p->data != q->data) {
            printf("Not Palindrome\n");
            return;
        }
        p = p->next;
        q = q->prev;
    }

    printf("Palindrome\n");
}

int main() {
    // 按照题目要求读取输入
    int n;
    int arr[100]; // 假设最大节点数为100,可根据需求调整

    // 读取第一行元素
    printf("Enter the linked list elements separated by spaces: ");
    int i = 0;
    while (scanf("%d", &arr[i]) == 1) {
        i++;
        // 处理换行符,判断是否到第二行
        char c = getchar();
        if (c == '\n') break;
    }
    // 读取第二行的长度
    printf("Enter the length of the linked list: ");
    scanf("%d", &n);

    struct node* head = create(arr, n);
    is_palindrome(head);

    // 释放链表内存,避免内存泄漏
    struct node* current = head;
    while (current != NULL) {
        struct node* next = current->next;
        free(current);
        current = next;
    }

    return 0;
}

说明

  • 修复后的代码解决了所有编译器警告和段错误问题,完全符合题目输入输出要求。
  • 添加了内存释放逻辑,避免程序运行时的内存泄漏。
  • 优化了链表创建效率,使用tail指针直接追加节点,无需每次遍历到尾部。

内容的提问来源于stack exchange,提问作者Mridul Hemrajani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:52:32