【问题标题】:Access variables in struct from void pointer从 void 指针访问结构中的变量
【发布时间】:2018-12-05 17:33:29
【问题描述】:

我想知道是否有一种方法可以访问 struct 中由 void* 指向的数据成员?我试图解释的内容有望在我的示例代码中更加明显:

int main()
{
  struct S
  {
    int val;
  };
  S s;
  s.val = 5;

  void* p;
  p = malloc(sizeof(S));
  *(struct S*) p = s;
  std::cout<< *(struct S*)p.val << std::endl;

}

我已经将p 作为*(int*)p 运行了这个精确的代码转换,它打印得很好,但是,使用上面的精确代码会导致编译错误。还没有找到一个完全完成这个任务的例子。 struct 转换后是否可以访问其数据成员?为什么或者为什么不?如果是这样,如何?

【问题讨论】:

  • std::cout&lt;&lt; (*(struct S*)p).val((struct S*)p)-&gt;val 。你只需要一对额外的括号。

标签: c++11 struct casting void-pointers data-members


【解决方案1】:

. 运算符的 precedence 比 C 风格的演员高。所以*(struct S*)p.val 被视为*((struct S*)(p.val)),这没有意义,因为p 是一个指针并且没有成员。

所以你需要括号来指定你的意图:

std::cout<< (*(struct S*)p).val << std::endl;

或者等价的,

std::cout<< static_cast<S*>(p)->val << std::endl;

[而且:声明*(struct S*) p = s; 在技术上具有未定义的行为,即使所有大多数实现都允许它。这是因为 C++ 有关于何时创建对象的规则,并且该地址之前没有 S 类型的对象,并且赋值不会创建对象,除非涉及联合成员的某些情况。没有这个问题的类似声明是new(p) S{s};

另外:在 C++ 中使用mallocvoid* 通常不是一个好主意。 malloc 只能在与需要它的 C 库交互时使用。 void* 似乎有用的任何事情都可以使用模板更安全地完成。在少数情况下,void* 可能是做某事或“巧妙”避免代码重复或其他事情的唯一方法,但仍需谨慎使用它,并始终极其谨慎。]

【讨论】:

  • 感谢您的回复!这是非常有见地和直截了当的。我也对使用void* 持怀疑态度。我的情况是我的子类基本上从基类中获取结构。问题是直到运行时我才知道将提供哪种类型的struct。所以void* 是我尝试“捕获”struct 的方式,无论其类型如何。有什么想法或想法吗?
  • 可能是接口加模板实现之类的东西,或者可能是 std::variant(如果 C++17 不可用,则可能是 boost::variant)。但是如果没有更多细节就很难说。也许您可以就此提出另一个问题。
  • 酷,谢谢!性能是一个巨大的考虑因素并且非常关键。我研究了boost::variant,但一直找不到时间复杂性。我会尝试更深入地研究它。
猜你喜欢
  • 2012-02-03
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-14
  • 1970-01-01
相关资源
最近更新 更多