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

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是否超过当前链表长度,边界场景下极易出现空指针解引用。
修复方案
  1. 先实现对应类型的比较函数,比如int类型的比较逻辑:
bool int_eq(elem_t a, elem_t b) {
    return a.key == b.key;
}
  1. 修改测试代码,创建链表时传入合法的比较函数:
list_t *list = linked_list_create(int_eq);
  1. 修复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;
}
  1. 修正linked_list_contains的判断逻辑:
if (list->compare(cursor->element, element)) 
{
  return true;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:18:03