我想在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;
}
答案 0 :(得分:0)
第一步是正确获取连接节点的所有详细信息。 @chux在注释中有很好的建议-只需首先使用int
或float
类型对其进行实施,以确保其正确。
更大的问题是要用什么代替/*some parameters*/
,以使列表通用。具体来说,应该为add_node
函数的“ value”参数使用哪种类型。
您可以与任何其他类型自由地来回转换的唯一类型是void*
。您可以只将指针的副本直接存储在节点中-但这意味着您需要确保它们指向的变量永远不会超出范围。您永远无法将堆栈局部变量的地址添加到列表中。
有几种解决方法。
您可以跟踪项目大小,并使用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))
这些策略的缺点是没有类型安全性。编译器不会检测是否将字符串传递到浮点列表。
您可以使用宏为可列出的类型生成特定的函数
#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 ++模板版本一样工作,您必须在其中确保为使用的每种不同类型生成的代码都有一个副本。