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

排查C语言指针练习脚本中的Segmentation Fault错误

Hey there! Let's break down the issues causing your segmentation fault and fix your code step by step.

Key Issues Leading to Segmentation Fault & Bugs

1. 野指针访问(Segmentation Fault的核心原因)

In your append_list function, you're creating struct IntItem addition as a local stack variable. When the function finishes executing, this stack memory gets reclaimed by the system. Any later attempts to access ls->head or ls->tail (which point to this now-invalid memory) result in a wild pointer dereference—this is exactly what's triggering your segmentation fault.

Fix: Use dynamic memory allocation (malloc) to create new nodes on the heap, so the memory persists after the function returns:

#include <stdio.h>
#include <stdlib.h> // 引入malloc/free/exit所需头文件
#include <errno.h>   // 用于perror输出错误信息

void append_list(struct IntList* ls, int item){
    struct IntItem* addition = malloc(sizeof(struct IntItem));
    if (!addition) { // 必须检查malloc是否分配成功!
        perror("Failed to allocate memory for new list item");
        exit(EXIT_FAILURE);
    }
    addition->next = NULL;
    addition->value = item;

    if (!ls->head) { // 列表为空时,头和尾都指向新节点
        ls->head = addition;
        ls->tail = addition;
    } else {
        ls->tail->next = addition;
        ls->tail = addition;
    }
}

另外,记得在程序结束时释放链表内存,避免内存泄漏:

void free_int_list(struct IntList* ls) {
    struct IntItem* current = ls->head;
    while (current) {
        struct IntItem* temp = current;
        current = current->next;
        free(temp);
    }
    ls->head = NULL;
    ls->tail = NULL;
}

在main函数末尾调用free_int_list(&ls);即可。

2. reduce函数中的多处问题

a. 未处理空列表情况

如果传入的列表为空,xs.head是NULL,执行struct IntItem current = *xs.head;会直接解引用空指针,引发崩溃。需要先添加前置检查:

b. 初始值设置错误与循环逻辑遗漏

  • 你的running初始值设为0,当使用max函数时,如果列表全是负数,结果会返回0而非列表中最大的负数。应该将running初始化为第一个元素的值。
  • 循环条件while (current.next)会跳过最后一个元素(因为最后一个节点的next是NULL),需要修改循环逻辑遍历所有非空节点。

c. 值传递的性能问题

将struct IntList按值传递会复制整个结构体,对于大列表会浪费内存,建议改为传递指针提升性能。

修复后的reduce函数:

int reduce(struct IntList* xs, int (*opy)(int, int)){
    if (!xs->head) {
        return 0; // 如果需要空列表返回其他值,可以自行调整
    }
    struct IntItem* current = xs->head->next;
    int running = xs->head->value;

    while (current) {
        running = opy(running, current->value);
        current = current->next;
    }
    return running;
}

记得同步修改main中的调用代码,传递指针:

printf("Sum: %i\n", reduce(&ls, sum));
printf("Max: %i\n", reduce(&ls, max));

3. max函数的逻辑错误

你当前的max函数在x == y时会返回0(因为x>y和y>x都会被判定为0),替换为更简洁正确的实现:

int max(int x, int y){
    return x > y ? x : y;
}

完整修复后的代码

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

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

struct IntList {
    struct IntItem* head;
    struct IntItem* tail;
};

void append_list(struct IntList* ls, int item){
    struct IntItem* addition = malloc(sizeof(struct IntItem));
    if (!addition) {
        perror("Failed to allocate memory for new list item");
        exit(EXIT_FAILURE);
    }
    addition->next = NULL;
    addition->value = item;

    if (!ls->head) {
        ls->head = addition;
        ls->tail = addition;
    } else {
        ls->tail->next = addition;
        ls->tail = addition;
    }
}

void free_int_list(struct IntList* ls) {
    struct IntItem* current = ls->head;
    while (current) {
        struct IntItem* temp = current;
        current = current->next;
        free(temp);
    }
    ls->head = NULL;
    ls->tail = NULL;
}

int sum(int x, int y){
    return x + y;
}

int max(int x, int y){
    return x > y ? x : y;
}

int reduce(struct IntList* xs, int (*opy)(int, int)){
    if (!xs->head) {
        return 0;
    }
    struct IntItem* current = xs->head->next;
    int running = xs->head->value;

    while (current) {
        running = opy(running, current->value);
        current = current->next;
    }
    return running;
}

int main(void) {
    struct IntList ls = {NULL, NULL};
    printf("Start Script\n");
    append_list(&ls, 1);
    append_list(&ls, 2);
    append_list(&ls, 3);
    printf("List Complete\n");
    printf("Sum: %i\n", reduce(&ls, sum));
    printf("Max: %i\n", reduce(&ls, max));
    free_int_list(&ls);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 15:52:58