从void指针访问struct中的变量

时间:2018-06-26 22:45:36

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

我想知道是否有一种方法可以访问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的数据成员?为什么或者为什么不?如果是这样,怎么办?

1 个答案:

答案 0 :(得分:1)

.运算符比C样式强制转换具有更高的precedence。因此*(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*可能是做某事或“明智地”避免代码重复或某事的唯一方法,但仍要谨慎使用,并且要格外小心。]