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

C语言链表removeNode返回指针后free触发段错误如何解决

问题原因&修复方案
  • 遍历删除逻辑存在空指针访问
    removeNode的while循环仅判断了current != NULL就直接执行current = current->next,后续没有判断current是否为空就调用strcmp(current->data, name),当链表遍历到末尾current为NULL时,访问current->data会直接触发段错误。
  • 插入存储的名称带前缀,删除时匹配失败
    插入节点时直接复制了完整的argv[x](带+前缀,比如+bill),但删除时传入的是argv[x]+1(去掉-前缀的纯名称,比如bill),二者字符串不相等永远匹配不到节点,会导致遍历走到链表末尾触发上述空指针访问。
  • 字符串常量被free触发未定义行为
    removeNode匹配失败时返回的是字符串常量"error0",但main函数中不管返回值是什么都会执行free(name),free常量区的字符串会触发内存错误。
修复后完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node {
    char *data;
    struct node *next;
};

// 补充打印链表函数
void printList(struct node **head) {
    struct node *current = *head;
    while (current != NULL) {
        printf("%s ", current->data);
        current = current->next;
    }
    printf("\n");
}

int insert(struct node ** head, char * name) {
    struct node * newNode = (struct node * ) malloc(sizeof(struct node));
    newNode->data = name;
    newNode->next = NULL;
    struct node * current = * head;
    if ( * head == NULL) {
        * head = newNode;
        return 1;
    }
    while (current->next != NULL) {
        current = current->next;
    }
    current->next = newNode;
    return 1;
}

char * removeNode(struct node ** head, char * name) {
    struct node * current = * head;
    struct node * previous;

    if (current == NULL) {
        return "error0";
    }

    if (strcmp(current->data, name) == 0) {
        char * data = current->data;
        * head = current->next;
        free(current);
        printf("Removed %s \n", name);
        return data;
    }
    // 修复遍历逻辑,current下一个节点不为空时才进入后续判断
    while (current->next != NULL) {
        previous = current;
        current = current->next;
        if (strcmp(current->data, name) == 0) {
            char * data = current->data;
            previous->next = current->next;
            free(current);
            printf("Removed %s \n", name);
            return data;
        }
    }
    return "error0";
}

int main(int argc, char * argv[]) {
    printf("Author : Torin Costales \n");
    struct node * head = NULL;
    for (int x = 1; x < argc; x++) {
        if (argv[x][0] == '+') {
            // 修复:只复制+后面的纯名称,不保留前缀
            char * name = malloc(strlen(argv[x] + 1) + 1);
            if (name == NULL) return EXIT_FAILURE;
            strcpy(name, argv[x] + 1);
            printf("adding %s \n", name);
            insert( & head, name);
            printf("List: ");
            printList( & head);
        } else if (argv[x][0] == '-') {
            printf("removing %s \n", argv[x] + 1);
            char * name = removeNode( & head, argv[x] + 1);
            // 修复:仅当返回值不是常量error0时才执行free
            if (strcmp(name, "error0") != 0) {
                free(name);
            } else {
                printf("Remove failed: %s not found\n", argv[x]+1);
            }
            printList( & head);
        }
    }
    // 补充:程序退出前释放剩余节点避免内存泄漏
    struct node *tmp;
    while (head != NULL) {
        tmp = head;
        head = head->next;
        free(tmp->data);
        free(tmp);
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:06:03