当前位置: 首页 > 知识库问答 >
问题:

从指向某个成员的指针获取指向对象的指针

戴原
2023-03-14

假设有一个结构

struct Thing {
  int a;
  bool b;
};

我得到一个指向该结构的成员b的指针,比如作为某个函数的参数:

void some_function (bool * ptr) {
  Thing * thing = /* ?? */;
}

如何获取指向包含对象的指针?最重要的是:在不违反标准中的某些规则的情况下,也就是说,我想要标准定义的行为,而不是未定义或实现定义的行为。

附带说明:我知道这规避了类型安全。

共有3个答案

秦弘亮
2023-03-14
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的指针。

金子平
2023-03-14
void some_function (bool * ptr) {
  Thing * thing = (Thing*)(((char*)ptr) - offsetof(Thing,b));
}

我认为没有UB。

艾令雪
2023-03-14

如果您确定指针确实指向结构中的成员 b,就像有人这样做一样

Thing t;
some_function(&t.b);

然后,您应该能够使用< code>offsetof宏来获取指向该结构的指针:

std::size_t offset = offsetof(Thing, b);
Thing* thing = reinterpret_cast<Thing*>(reinterpret_cast<char*>(ptr) - offset);

请注意,如果指针ptr实际上没有指向Thing::bmember,那么如果您使用指针 Thing

 类似资料:
  • 我正在学习如何在C中使用并写了以下示例: 问:是否保证在所有情况下指向一个结构的指针都是指向它的第一个元素的完全相同的指针? 在这种特殊的情况下,它能像我预期的那样工作,但我不确定它是否能得到保证。编译器可以在开始时插入一些填充吗? 我唯一能找到的关于结构类型布局的是N1570的类型: 结构类型描述了一组按顺序分配的非空成员对象(在某些情况下,还包括一个不完整的数组),每个对象都有一个可选的指定名

  • 所以我的教授喜欢用我们应该弄清楚的论文上的代码来测试我们。我不会发布代码,因为我不是在寻找答案,这只是他曾经让我们感到困惑的一件事是,当他初始化一个类的对象,然后初始化另一个类的指针指向上述对象时。它让我感到困惑,这是一个如此具体的问题,我不知道如何搜索它。例: “d- 当指针来自一个类却指向另一个类的对象时,它到底在做什么?我知道这个问题以前可能已经被回答过了,但是我在任何地方都找不到它,所以我

  • 指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。 如果一个指针指向的是另外一个指针,我们就称它为 二级指针,或者 指向指针的指针。 假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示: 将这种关系转换为C语言代码: 指针变

  • 在下面给出的代码中,我声明了一个指向int的指针,我们都知道memcpy返回一个指向目标字符串的空指针,所以如果ptr是指向int的指针,那么为什么printf(“%s”,ptr);是完全有效的,ptr毕竟不是指向char的指针。

  • GCC 8.2.1和MSVC 19.20编译以下代码,但Clang 8.0.0和ICC 19.0.1无法这样做。 Clang 8.0.0 的错误消息如下: 我注意到它在两种情况下可以用Clang编译: 从最后一个定义中删除括性 将线 替换为

  • 6. 指向指针的指针与指针数组 指针可以指向基本类型,也可以指向复合类型,因此也可以指向另外一个指针变量,称为指向指针的指针。 int i; int *pi = &i; int **ppi = &pi; 这样定义之后,表达式*ppi取pi的值,表达式**ppi取i的值。请读者自己画图理解i、pi、ppi这三个变量之间的关系。 很自然地,也可以定义指向“指向指针的指针”的指针,但是很少用到: int