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

C语言链表程序仅在自动评分器运行时触发LeakSanitizer内存泄漏求助

内存泄漏原因定位

你的代码的内存泄漏出现在Insert函数逻辑里:

  • 函数开头就调用malloc申请了新节点内存temp,之后遍历链表检查待插入值x是否已存在,如果发现存在就直接return,此时已经申请的temp内存没有被释放,直接发生泄漏。
  • 自动评分器的测试用例包含了重复插入相同值的场景,会触发这个泄漏路径;你手动测试时没有覆盖重复插入的场景,所以不会触发泄漏,自然看不到报错。
  • 内存泄漏本身不会影响程序运行逻辑和输出结果,程序退出后系统会自动回收所有进程内存,所以你手动运行时只会觉得程序完全正常,只有开启内存检测工具(如LeakSanitizer)时才会被捕获。
修复方案(不影响原有功能和输出)

你可以直接调整Insert函数的逻辑顺序,先检查待插入值是否存在,确认不存在后再申请内存,修改后的Insert函数如下:

void Insert(int x){
    struct Node* ptr = head;
    
    // 先检查是否已经存在,不存在再申请内存
    while(ptr != NULL){
        if(ptr->data == x){return;}
        ptr = ptr->next;
    }
    // 确认需要插入,再malloc申请节点
    struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    
    //check if head is greater
    if(head == NULL || head->data > x){
        temp->data = x;
        temp->next = head;
        head = temp;  
    }else{
        ptr = head;
        while(ptr->next != NULL && ptr->next->data < x){
            ptr = ptr->next;
        }
        
        temp->data = x;
        temp->next = ptr->next;
        ptr->next = temp;
    }
   
}

如果你不想调整代码顺序,也可以在检查到x已存在的return前加free(temp)释放已申请的内存,效果完全一致。

可选优化(符合内存安全规范)

如果需要完全符合内存检测的严格要求,可以在main函数返回前遍历剩余链表节点,逐个释放所有还存在的节点内存,避免进程退出前的残留节点被误判为泄漏:

// 加在main函数return 0之前
struct Node* temp = head;
while(temp != NULL){
    struct Node* next = temp->next;
    free(temp);
    temp = next;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:36:04