我需要创建一个完全通用的链表,它可以包含由枚举...
指定的任何类型的数据列表中的节点具有以下结构:
__________________
|_____|_____|_____|
第一个字段是sizeof(nodeType)字节,包含存储的信息类型。下一个字段的地址包含信息变量的地址。下一个字段具有下一个节点的地址,该节点可以是简单节点或另一个链接列表。
基本上,我有一个nodeType枚举:
typedef enum{
STRING, INT, NIL, LIST
} nodType;
我已将内存分配给节点指针,如下所示:
nodeType* node = malloc(sizeof(nodeType) + 2*sizeof(char*));
第一个sizeof(nodeType)字节包含存储的inofrmation类型。我通过表达式为其指定了值STRING:
*node = STRING;
现在,我希望下一个sizeof(char *)字节存储char *指针的地址。 (所有指针在一台机器上的大小相同?(是的,适合我))..所以,我给它分配一个值,如:
char* str = strdup("Hello");
(char**)(char*(node) + sizeof(nodeType)) = &str;
但GCC标记错误,因为赋值运算符的LHS不是左值。 我需要为该地址赋值,以便继续构建该列表。 除了使用struct之外,还有一些优雅的方法吗?
答案 0 :(得分:4)
你忘了取消引用:
*(char***)((char*)node + sizeof(nodeType)) = &str;
取消引用操作的结果始终是左值。通常,如果要将内存位置p
视为指向T
类型的变量,则需要将其转换为T *
并取消引用:
*(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;
请注意,我选择将字符串直接存储为char *
,将不存储为char *
的指针。统一主题应该是列表节点拥有p->data
并且应该无条件地删除节点时说free(p->data);
。