如何为通过指针算法计算的内存地址赋值?

时间:2012-10-06 12:08:15

标签: c pointers lvalue

我需要创建一个完全通用的链表,它可以包含由枚举...

指定的任何类型的数据

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

  __________________
  |_____|_____|_____|

第一个字段是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之外,还有一些优雅的方法吗?

1 个答案:

答案 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);