C语言聊天室服务端双向链表删除指定客户端节点崩溃问题求解
双向链表删除节点函数问题排查及修复方案
原有函数存在的核心问题
- 重复释放内存:单节点场景下
p_head和p_tail指向同一块内存,连续调用两次free属于非法操作,直接触发崩溃。 - 条件判断逻辑完全错乱:第二个分支判断
p_list->p_tail != NULL在链表非空时永远成立,后续“删除尾节点”“链表为空”的分支永远无法命中,逻辑完全失效。 - 未处理头节点删除场景:待删除节点为头节点时,
p_client->p_previous为NULL,直接访问p_new_previous->p_next会触发空指针崩溃。 - 尾节点删除逻辑错误:即使尾节点分支能命中,代码里
p_new_previous->p_previous = p_list->p_tail属于指针赋值错误,会破坏链表结构。 - 未更新链表计数:删除节点后没有对
p_list->count执行减1操作,后续依赖计数的逻辑都会出错。 - 缺少入参校验:没有判断
p_list、p_client是否为空,也没有判断链表是否为空就直接访问结构体成员,空链表调用会直接崩溃。
修复后的完整代码
void release_client(LIST *p_list, CLIENT *p_client) { // 入参合法性校验 if (!p_list || !p_client || p_list->count == 0) { printf("Invalid parameter or empty list, unable to delete client !!!\n"); return; } CLIENT *prev = p_client->p_previous; CLIENT *next = p_client->p_next; // 处理前驱节点的后继指针 if (prev != NULL) { prev->p_next = next; } else { // 待删除节点是头节点,更新链表头指针 p_list->p_head = next; } // 处理后继节点的前驱指针 if (next != NULL) { next->p_previous = prev; } else { // 待删除节点是尾节点,更新链表尾指针 p_list->p_tail = prev; } // 释放当前节点内存 free(p_client); // 更新链表计数 p_list->count--; }
逻辑说明
修复后的代码覆盖了所有删除场景:单节点删除、头节点删除、尾节点删除、中间节点删除,不需要多分支冗余判断,逻辑统一且不会出现空指针访问、重复释放的问题,和你现有的插入逻辑完全兼容。
内容的提问来源于stack exchange,提问作者cryptoTuke
相关产品推荐
相关产品推荐

