双向链表重复元素删除代码报错:Thread 1: EXC_BAD_ACCESS (code=1, address=0x10) 原因排查
双向链表重复元素删除代码报错:Thread 1: EXC_BAD_ACCESS (code=1, address=0x10) 原因排查
嘿,我来帮你拆解这个报错的问题~你遇到的Thread 1: EXC_BAD_ACCESS本质是访问了非法内存,具体到你代码里的(index->leftLink->rightLink)=(index->rightLink);这一行,核心问题出在删除节点后的指针处理逻辑上,我给你一步步分析:
直接报错原因:野指针访问
你在内层循环找到重复节点后,把index赋值给temporaryStorer,修改完链表链接就直接free(temporaryStorer)了。但free之后,index已经变成了野指针(指向被操作系统回收的内存),而内层循环的下一次迭代还会执行index = index->rightLink——这时候你在访问一块已经失效的内存里的rightLink,完全是非法操作,大概率触发内存访问错误。
代码里的其他隐形问题
除了直接导致报错的野指针,你的代码还有两个潜在问题:
- 内存泄漏风险:你把
free(temporaryStorer)放在了if (index->rightLink != NULL)的分支里,这意味着如果index是链表最后一个节点(rightLink为NULL),你就不会释放这个重复节点,长期运行会造成内存泄漏。 - 循环指针更新逻辑错误:删除节点后没有提前保存下一个节点的地址,导致无法正确推进循环。
修正后的代码
我调整了你的代码逻辑,解决了上述所有问题:
typedef struct NODE { struct NODE* leftLink; int info; struct NODE* rightLink; } NODE; NODE* deleteDuplicates(NODE* head){ NODE* current; NODE* temporaryStorer; NODE* index; NODE* nextNode; // 新增临时变量,提前保存下一个节点地址 if (head == NULL) { printf("List is empty\n"); return head; } else { // 外层循环遍历每个节点 for (current = head; current != NULL; current = current->rightLink) { // 内层循环遍历当前节点之后的所有节点 for (index = current->rightLink; index != NULL;) { // 这里不再自动更新index,手动处理 if (index->info == current->info) { // 先保存下一个节点,避免free后丢失 nextNode = index->rightLink; temporaryStorer = index; // 修改前驱节点的右指针,跳过当前重复节点 index->leftLink->rightLink = nextNode; // 如果不是最后一个节点,修改后继节点的左指针 if (nextNode != NULL) { nextNode->leftLink = index->leftLink; } // 释放重复节点 free(temporaryStorer); // 让index跳转到下一个节点,继续循环 index = nextNode; } else { // 没有重复,正常移动index指针 index = index->rightLink; } } } } return head; }
关键修正点说明
- 新增
nextNode保存下一个节点:在删除index节点前先记录它的下一个节点地址,这样即使index被释放,也能正确推进循环,避免野指针。 - 手动控制
index的更新:内层循环的index更新不再写在for循环头部,而是根据是否删除节点来处理,确保每次循环的index都是合法指针。 - 调整
free的位置:把free(temporaryStorer)移到分支外面,确保所有重复节点都会被释放,不会出现内存泄漏。
备注:内容来源于stack exchange,提问作者Marc Newsom
相关产品推荐
相关产品推荐

