如何在C中实现泛型链表

时间:2018-12-12 18:08:59

标签: c generics struct linked-list adt

我想在c中创建一个通用的链表,下面是创建它的方法,但是我不确定这是否是正确的方法,我在堆中为结构uniqueOrderedList_t分配了一个新的内存,然后在堆中为该元素分配一个新的内存,因为我希望它是通用的,这是正确的方法吗?以及“下一个指针”呢,我还需要为其分配内存吗?

#the .h file contain:
typedef void* Element;
typedef struct uniqueOrderedList_t* UniqueOrderedList;
UniqueOrderedList uniqueOrderedListCreate(/*some parameters*/);

#the .c file:
struct uniqueOrderedList_t{
  Element element;
  struct uniqueOrderedList_t* next;  
};

uniqueOrderedList uniqueOrderedListCreate(/*some arguments*/){
   UniqueOrderedList newList = malloc(sizeof(*newList));
 if(!newList){
  return NULL;
 }
 newLust->element = malloc(sizeof(Element));
   if(!element){
     return NULL;
   }
 newList->next = NULL;

}

1 个答案:

答案 0 :(得分:0)

第一步是正确获取连接节点的所有详细信息。 @chux在注释中有很好的建议-只需首先使用intfloat类型对其进行实施,以确保其正确。

更大的问题是要用什么代替/*some parameters*/,以使列表通用。具体来说,应该为add_node函数的“ value”参数使用哪种类型。

您可以与任何其他类型自由地来回转换的唯一类型是void*。您可以只将指针的副本直接存储在节点中-但这意味着您需要确保它们指向的变量永远不会超出范围。您永远无法将堆栈局部变量的地址添加到列表中。

有几种解决方法。

  1. 您可以跟踪项目大小,并使用malloc和memcpy创建足以容纳数据的节点。

    a。创建列表时声明项目大小。 list = makelist(sizeof(myType))。这对于存储大小的唯一头类型将是最好的选择。

    b。强制用户传递每个节点的大小:list = add_node(list, &item, sizeof(item))

    c。策略1b,但使用宏传递大小:#define add_node(l,item) (add_node_impl(l, &item, sizeof(item))

这些策略的缺点是没有类型安全性。编译器不会检测是否将字符串传递到浮点列表。

  1. 您可以使用宏为可列出的类型生成特定的函数

    #define VALUE_T MyType #define LISTOF(type) type ## list LISTOF(VALUE_T) add_node(LISTOF(VALUE_T) l, VALUE_T v) { /* alloc(sizeof(VALUE_T)),copy from &v, link into l */ }

此策略更具类型安全性,但过于繁琐,难以正确执行,也难以调试。最终,它像更明确的C ++模板版本一样工作,您必须在其中确保为使用的每种不同类型生成的代码都有一个副本。