简体   繁体   中英

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. 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:

 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. I assigned it the value STRING by the expression:

 *node = STRING;

Now, I want the next sizeof(char*) bytes store the address of a char* pointer. (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. Is there some elegant way of doing that in c apart from using a struct??

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:

*(T*)(p) = my_t_value;

This applies to your situation for T = char ** and 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 * . The unifying theme should be that the list node owns p->data and should say free(p->data); upon node removal unconditionally.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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