链表中元素比较功能的实现
Posted
技术标签:
【中文标题】链表中元素比较功能的实现【英文标题】:Implementation of element compare function in linked list 【发布时间】:2021-11-27 21:10:45 【问题描述】:我正在尝试实现一个作为链表结构一部分的函数,但由于某种原因,我的测试中不断出现分段错误。我不确定故障是由我在列表结构中的 compare 定义引起的,还是我在 linked_list_create 函数中实现它的方式。我已经使用 GDB 调试代码很长一段时间了。我可以看到的一件事是测试中的 current_entry 不包含任何值,但我不知道这会如何导致此问题。
//structs
union elem
int key;
char *value;
void *extra;
;
typedef union elem elem_t;
#define int_elem(x) (elem_t) .key=(x)
#define val_elem(x) (elem_t) .value=(x)
#define ptr_elem(x) (elem_t) .extra=(x)
typedef struct link link_t;
typedef struct list list_t;
/// Compares two elements and returns true if they are equal
typedef bool(*eq_function)(elem_t a, elem_t b);
struct link
elem_t element; //data
link_t *next; //link
;
struct list
link_t *first;
link_t *last;
eq_function compare;
;
//Function
list_t *linked_list_create(eq_function compare)
list_t *result = calloc(1, sizeof(list_t)); // allocated memory for list
if (result)
result->first = result->last = calloc(1, sizeof(struct link));
result->compare = compare;
return result;
bool linked_list_contains(list_t *list, elem_t element)
for (link_t *cursor = list->first->next; cursor; cursor = cursor->next)
if (list->compare(cursor->element, element) == 0)
return true;
;
return false;
void linked_list_append(list_t *list, const elem_t element)
list->last->next = link_create(element, NULL);
list->last = list->last->next;
///inserts a link in the list dependent on link index
void linked_list_prepend(list_t *list, const elem_t element)
linked_list_insert(list, 0, element);
elem_t linked_list_remove(list_t *list, const int index)
link_t *tmp = list->first; //tmp acts as a cursor
for (int i = 0; i < (index-1); i++)
tmp = tmp->next; //at end of loop tmp is the link we wish to remove
;
link_t *to_remove = tmp->next;
elem_t returnval = to_remove->element;
link_destroy(to_remove); //destroys the link
return returnval;
///inserts a link in a list given an index
void linked_list_insert(list_t *list, const int index, const elem_t value)
link_t *previous = list->first; //first link in list
for (int i = 0; i < (index-1); i++)
previous = previous->next;
;
previous->next = link_create(value, previous->next); //inserts created link
//Test
void test_remove1()
list_t *list = linked_list_create(NULL);
elem_t valtest = int_elem(7);
for (int i = 0; i < 8; i++)
linked_list_append(list, int_elem(0));
;
linked_list_insert(list, 5, valtest);
linked_list_remove(list, 5);
bool result = linked_list_contains(list, valtest);
CU_ASSERT_FALSE(result);
linked_list_destroy(list);
测试在 CUnit 中,由于linked_list_contains 第 95 行的分段错误而未完成。
【问题讨论】:
这些宏 #define int_elem(x) (elem_t) .key=(x) #define val_elem(x) (elem_t) .value=(x) #define ptr_elem(x) (elem_t) .extra=(x) 只会使您的代码不可读。 "我已经使用 GDB 坐了很长时间了"。好的。所以告诉我们你发现了什么。调试器至少会为您提供触发 seg 错误的确切代码行。所以把它放到你的帖子里。 @davdavdav2 这个语句结果->first = result->last = calloc(1, sizeof(struct link));在函数linked_list_create 中也没有任何意义。 @VladfromMoscow 怎么样?它至少使测试更容易,它们只需返回元素的 int、ptr 或 val。linked_list_create(false);
您正在将compare
函数设置为false
。但是false
不是函数。你希望它如何工作?为什么当它使用布尔值作为函数时它会崩溃?
【参考方案1】:
linked_list_create(false)
将compare
函数设置为false
。但是false
不是一个函数,所以它在尝试调用compare
函数时会崩溃也就不足为奇了。
typedef bool(*eq_function)(elem_t a, elem_t b);
这是compare
函数的函数原型。这意味着它是一个接受两个elem_t
参数并返回一个bool
的函数。所以你需要定义一个该类型的函数并相应地设置列表。
例如:
bool my_eq_function (elem_t a, elem_t b)
// Implement real compare logic here
return false;
然后设置它:
linked_list_create(my_eq_function);
【讨论】:
以上是关于链表中元素比较功能的实现的主要内容,如果未能解决你的问题,请参考以下文章