简体   繁体   English

如何将值分配给通过指针算术计算的内存地址?

[英]How to assign value to a memory address calculated by pointer arithmetic?

I need to create a completely generic linked list that can contain any type of data specified by an enum... 我需要创建一个完全通用的链表,其中可以包含枚举指定的任何类型的数据...

A node of the list has the structure: 列表的节点具有以下结构:

  __________________
  |_____|_____|_____|

The first field is of sizeof(nodeType) bytes containing the type of information stored. 第一个字段的大小为sizeof(nodeType)字节,其中包含存储的信息类型。 The next field has an address that contains address of the information variable. 下一个字段的地址包含信息变量的地址。 The next field has the address of the next node which can be a simple node or yet another linked list.. 下一个字段具有下一个节点的地址,该地址可以是简单节点或另一个链表。

Basically, I have a nodeType enum as: 基本上,我有一个nodeType枚举为:

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

I have allocated memory to a node pointer like this: 我已经将内存分配给这样的节点指针:

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

The first sizeof(nodeType) bytes contain the type of inofrmation stored. 第一个sizeof(nodeType)字节包含存储的信息类型。 I assigned it the value STRING by the expression: 我通过表达式为它分配了值STRING:

 *node = STRING;

Now, I want the next sizeof(char*) bytes store the address of a char* pointer. 现在,我希望下一个sizeof(char *)字节存储char *指针的地址。 (All pointers are of the same size on a machine?(yes, acc to me)).. So, I assign a value to it like: (一台机器上的所有指针大小都相同吗?(是的,根据我的意思)。)因此,我为其分配了一个值,例如:

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

But GCC flags an error as the LHS of assignment operator is not an lvalue.. I need to assign value to that address in order to go ahead to build that list. 但是GCC会标记错误,因为赋值运算符的LHS不是左值。我需要为该地址赋值,以便继续构建该列表。 Is there some elegant way of doing that in c apart from using a struct?? 除了使用struct之外,在c中还有一些优雅的方法吗?

You forgot to dereference: 您忘记了取消引用:

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

The result of a dereference operation is always an lvalue. 解引用操作的结果始终是左值。 In general, if you want to treat a memory location p as if it pointed to a variable of type T , you need to cast it to a T * and dereference: 通常,如果要将内存位置p视为指向T类型的变量,则需要将其强制转换为T *并取消引用:

*(T*)(p) = my_t_value;

This applies to your situation for T = char ** and p = (char *) node + sizeof(nodeType) . 这适用于T = char **p = (char *) node + sizeof(nodeType)


But this is just terrible design. 但这只是糟糕的设计。 No sane could should contain *** . 理智的人不能含有*** And moreover, you're potentially violating alignment constraints by assuming that all your elements follow contiguously in memory. 而且,通过假设所有元素在内存中连续跟随,您有可能违反对齐约束。 A much simpler way would be something like this: 更简单的方法是这样的:

struct Node
{
    struct Node * next;

    nodType type;
    void * data;
};

Usage: 用法:

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

Note that I chose to store a string directly as a char * , and not as a pointer to a char * . 请注意,我选择将字符串直接存储为char * ,而不是作为char *的指针。 The unifying theme should be that the list node owns p->data and should say free(p->data); 统一主题应该是列表节点拥有p->data并说free(p->data); upon node removal unconditionally. 无条件删除节点时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM