【问题标题】: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 不是函数。你希望它如何工作?为什么当它使用布尔值作为函数时它会崩溃?

标签: c struct linked-list comparison cunit


【解决方案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);

【讨论】:

    猜你喜欢
    • 2017-10-06
    • 1970-01-01
    • 2022-07-31
    • 2018-03-07
    • 2015-09-30
    • 1970-01-01
    • 2012-05-08
    相关资源
    最近更新 更多