C语言链表元素比较功能实现触发段错误问题求助
问题根因分析
- 空函数指针调用:测试代码中调用
linked_list_create(NULL)传入了空的比较函数指针,在执行linked_list_contains时直接调用list->compare,属于空指针解引用,这是触发段错误的直接原因。 - 删除节点后未修正链表指针:
linked_list_remove函数中,销毁待删除节点to_remove后,没有将前序节点tmp的next指针指向to_remove->next,导致链表出现野指针,后续遍历到该位置时会触发非法内存访问。同时如果删除的是链表最后一个节点,还需要同步更新list->last指针指向tmp,避免尾指针变为野指针。 - 比较逻辑写反:
eq_function的定义是两个元素相等时返回true,但linked_list_contains中判断条件为list->compare(...) == 0,即相等时反而不会返回true,逻辑完全倒置。 - 无参数合法性校验:所有链表操作函数都没有对入参合法性做校验,比如
list指针是否为空、传入的index是否超过当前链表长度,边界场景下极易出现空指针解引用。
修复方案
- 先实现对应类型的比较函数,比如int类型的比较逻辑:
bool int_eq(elem_t a, elem_t b) { return a.key == b.key; }
- 修改测试代码,创建链表时传入合法的比较函数:
list_t *list = linked_list_create(int_eq);
- 修复
linked_list_remove的指针逻辑:
elem_t linked_list_remove(list_t *list, const int index) { // 可根据需求补充index范围校验 assert(list != NULL); link_t *tmp = list->first; for (int i = 0; i < (index-1); i++) { tmp = tmp->next; assert(tmp != NULL); }; link_t *to_remove = tmp->next; assert(to_remove != NULL); elem_t returnval = to_remove->element; // 修正前序节点的next指针 tmp->next = to_remove->next; // 删除尾节点时同步更新链表last指针 if (to_remove == list->last) { list->last = tmp; } link_destroy(to_remove); return returnval; }
- 修正
linked_list_contains的判断逻辑:
if (list->compare(cursor->element, element)) { return true; }
内容的提问来源于stack exchange,提问作者fireproofiii
相关产品推荐
相关产品推荐

