0

我需要创建一个完全通用的链表,它可以包含枚举指定的任何类型的数据......

列表的一个节点具有以下结构:

  __________________
  |_____|_____|_____|

第一个字段是 sizeof(nodeType) 字节,包含存储的信息类型。下一个字段的地址包含信息变量的地址。下一个字段具有下一个节点的地址,它可以是一个简单的节点或另一个链表。

基本上,我有一个 nodeType 枚举为:

 typedef enum{
    STRING, INT, NIL, LIST
 } nodType;

我已经为这样的节点指针分配了内存:

 nodeType* node = malloc(sizeof(nodeType) + 2*sizeof(char*));

第一个 sizeof(nodeType) 字节包含存储的信息类型。我通过表达式为它分配了值 STRING:

 *node = STRING;

现在,我希望下一个 sizeof(char*) 字节存储 char* 指针的地址。(机器上的所有指针都具有相同的大小?(是的,根据我的说法)).. 所以,我给它分配了一个值,例如:

 char* str = strdup("Hello");
 (char**)(char*(node) + sizeof(nodeType)) = &str;

但是 GCC 会标记一个错误,因为赋值运算符的 LHS 不是左值。我需要为该地址分配值才能继续构建该列表。除了使用结构之外,在 c 中是否有一些优雅的方法可以做到这一点?

4

1 回答 1

4

你忘了取消引用:

*(char***)((char*)node + sizeof(nodeType)) = &str;

取消引用操作的结果始终是左值。通常,如果您想将内存位置p视为指向类型的变量T,则需要将其强制转换为 aT *并取消引用:

*(T*)(p) = my_t_value;

这适用于T = char **和的情况p = (char *) node + sizeof(nodeType)


但这只是糟糕的设计。任何理智的人都不应该包含***. 此外,假设您的所有元素在内存中连续跟随,您可能会违反对齐约束。一个更简单的方法是这样的:

struct Node
{
    struct Node * next;

    nodType type;
    void * data;
};

用法:

struct Node * p = malloc(sizeof *p);
p->next = NULL;
p->type = STRING;
p->data = str;

请注意,我选择将字符串直接存储为 a char *,而不是指向 a 的指针char *。统一的主题应该是列表节点拥有p->data并且应该free(p->data);在无条件删除节点时说。

于 2012-10-06T12:12:54.410 回答