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
相关产品推荐
相关产品推荐

