-1

Here we have our simple node struct which might be used to implement a double linked list.

template <class T>
struct node {

    node<T> *prev = NULL;
    node<T> *next = NULL;
    T data;
};

Supposing we don't know or have reference to a node object/instance, but we do have a pointer to it's data member. T data;

How can the host node object be referenced/found from the pointer to it's data member ?

tuk
  • 367
  • 1
  • 4
  • 10
  • 1
    You can't do it portably. You may find a way hacking about with the `offsetof` macro and `reinterpret_cast<>`ing all the things between `char *` and `node *`, but that's technically undefined behavior. If you need to express a two-way relationship, then use back pointers from each child node to its parent. – The Paramagnetic Croissant Feb 08 '15 at 12:54
  • You're asking about how to find the `head` of the list? `T* data;` looks weird BTW. – πάντα ῥεῖ Feb 08 '15 at 12:55
  • Do you really have pointer to the member (`pointer == &node.data`) or do you have the pointer stored in that member (`pointer == node.data`)? If the latter, you cannot find it. – StenSoft Feb 08 '15 at 13:06
  • Sorry,edited! it should read: T data not: T* data – tuk Feb 08 '15 at 16:59

1 Answers1

1

Elaborating on StenSoft comment, if you only know the value of the data member, you won't be able to get the struct containing it.

But if you know its address, say T** member_addr you can find the node :

void * ma = static_cast<void *>(member_addr); // convert pointer to void * : legal
intptr_t ima = static_cast<intptr_t>(ma); // convert void * to intptr_t : legal
intptr_t ina = ima - offsetof(struct node, data); // legal by definition of offestof
void * na = static_cast<void *>(ina); // convert intptr_t to void * : legal
struct node *pn = static_cast<node *>(na); // convert void * to pointer : legal provided the initial void * pointer points to a correct object

Of course all that is only legal for C++11 or above.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252