假设有一个结构
struct Thing {
int a;
bool b;
};
我得到了一个指向该结构的成员b
的指针,比如说作为某个函数的参数:
void some_function (bool * ptr) {
Thing * thing = /* ?? */;
}
如何获得指向包含对象的指针?最重要的是:在不违反标准中的某些规则的情况下,即我需要标准定义的行为,而不是未定义或实现定义的行为。
作为附注:我知道这避开了类型安全。
发布于 2015-11-23 19:47:23
如果您确定指针确实指向结构中的成员b
,就像有人这样做一样
Thing t;
some_function(&t.b);
然后,您应该能够使用offsetof
宏来获取指向该结构的指针:
std::size_t offset = offsetof(Thing, b);
Thing* thing = reinterpret_cast<Thing*>(reinterpret_cast<char*>(ptr) - offset);
请注意,如果指针ptr
实际上没有指向Thing::b
成员,那么如果您使用指针thing
,上面的代码将导致未定义的行为。
发布于 2015-11-23 19:47:18
void some_function (bool * ptr) {
Thing * thing = (Thing*)(((char*)ptr) - offsetof(Thing,b));
}
我认为没有UB。
发布于 2017-03-20 19:14:04
X* get_ptr(bool* b){
static typename std::aligned_storage<sizeof(X),alignof(X)>::type buffer;
X* p=static_cast<X*>(static_cast<void*>(&buffer));
ptrdiff_t const offset=static_cast<char*>(static_cast<void*>(&p->b))-static_cast<char*>(static_cast<void*>(&buffer));
return static_cast<X*>(static_cast<void*>(static_cast<char*>(static_cast<void*>(b))-offset));
}
首先,我们创建一些可以容纳X
的静态存储。然后,我们获得缓冲区中可能存在的X
对象的地址,以及该对象的b
元素的地址。
回溯到char*
,我们可以获得缓冲区中bool
的偏移量,然后我们可以使用它将指向实际bool
的指针调整回指向包含X
的指针。
https://stackoverflow.com/questions/33870219
复制相似问题