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

释放内存触发段错误原因排查?C语言链表代码求助

问题分析与修复方案

嗨,我一眼就瞅到问题出在哪了——你在list_free执行后调用list_print(start)时,访问了已经被释放的内存(也就是野指针),这才触发了段错误!

核心原因:值传递导致外部指针未更新

你的list_free函数参数是IntList *start,这是值传递——函数内部的start只是外部main里start的一个副本。你在函数里把内部的start一步步移到下一个节点,最后变成NULL,但这完全不会影响外部的start变量。等函数执行完,main里的start还是指向原来第一个节点的地址,而那个节点早就被free掉了,后续访问自然会炸。

修复方案:让list_free能修改外部指针

和你的list_append函数一样,把list_free改成接收指针的指针(IntList **start),这样就能在函数内部直接修改外部的start变量,把它置为NULL。修改后的list_free代码如下:

void list_free(IntList **start) {
    IntList *prev = *start;
    while (*start != NULL) {
        *start = (*start)->next;
        printf("Deleting %d\n", prev->value);
        free(prev);
        prev = *start;
    }
    printf("\n");
}

然后在main里调用的时候,要传指针的地址:

list_free(&start);

这样当所有节点都被释放后,main里的start会被置为NULL,后续调用list_print(start)就会直接跳过循环,不会访问无效内存了。

额外的小提醒

为了让代码更健壮,最好给malloc加个错误检查,避免内存分配失败导致的隐藏问题:

IntList *newel = malloc(sizeof(IntList));
if (newel == NULL) {
    perror("malloc failed");
    exit(EXIT_FAILURE);
}

完整修复后的代码

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

struct int_list { int value; struct int_list *next; };
typedef struct int_list IntList;

void list_print(IntList *start) {
    IntList *cur = start;
    while(cur != NULL) {
        printf("%d\n", cur->value);
        cur = cur->next;
    }
}

void list_append(IntList **start, int newval) {
    IntList *newel = malloc(sizeof(IntList));
    if (newel == NULL) {
        perror("malloc failed");
        exit(EXIT_FAILURE);
    }
    newel->value = newval;
    newel->next = NULL;
    if(*start == NULL) {
        *start = newel;
    } else {
        IntList *cur = *start;
        while(cur->next != NULL) {
            cur = cur->next;
        }
        cur->next = newel;
    }
}

void list_free(IntList **start) {
    IntList *prev = *start;
    while (*start != NULL) {
        *start = (*start)->next;
        printf("Deleting %d\n", prev->value);
        free(prev);
        prev = *start;
    }
    printf("\n");
}

int main(int argc, char *argv[]) {
    IntList *start = NULL;
    list_append(&start, 42);
    list_append(&start, 30);
    list_append(&start, 16);

    printf("\nList 1\n");
    list_print(start);
    printf("\n");

    list_free(&start);

    printf("Empty list:\n");
    list_print(start);
    printf("\n");

    return 0;
}

现在运行这段代码,就不会出现段错误了,空列表打印也会正常跳过循环~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:44:06