0

我正在尝试实现一个作为链表结构一部分的函数,但由于某种原因,我在测试中不断出现分段错误。我不确定故障是由我在列表结构中的比较定义引起的,还是我在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 行的分段错误而未完成。

4

1 回答 1

0

linked_list_create(false)compare函数设置为false。But falseis not a function 所以当它试图调用这个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);
于 2021-10-07T19:55:00.480 回答