繁体   English   中英

将内存投射为联合

[英]Casting memory to union

我想分配一些内存,将其初始化为某些值,然后将该内存的不同段转换为不同的结构。 如下所示:

union structA{
  __int8 mem[3];

  struct{
    unsigned field1 : 8;
    unsigned field2 : 12; 
    unsigned field3 : 4;
  };
};

struct structB{
  __int8 mem[10];
};


__int8 globalMem[128];

structA a1 <---- &globalMem[0]
structA a2 <---- &globalMem[10]
structB b1 <---- &globalMem[30]

我尝试使用reinterpret_cast,但没有得到任何编译器错误,但似乎我的变量( a1a2b1 )并未真正正确地分配/初始化。

是否知道为什么这样不起作用以及实现这样的正确方法的任何想法?

谢谢!

要实现您打算做的事情,需要使用reinterpret_cast

structA a1 = *reinterpret_cast<structA*>(&globalMem[0]);
structA a2 = *reinterpret_cast<structA*>(&globalMem[10]);
structB b1 = *reinterpret_cast<structB*>(&globalMem[30]);

这怎么了?

这需要格外小心,因为C ++ struct是一种特殊的class ,并且这种分配不尊重对象的语义(因为除非您在某些地方使用new放置,否则不同globalMem地址处的内容不会初始化为适当的对象。在您的代码中)。

在使用这种技巧之前,您还可以确保structA是可复制的( is_trivially_copyable<structA>::value在这里幸运的是正确的)。

另外,可能存在不遵守对齐约束的问题,因为globalMem没有对齐约束,但是根据编译器/体系结构, structA可能需要单词对齐。

最后,您倾向于认为structA的大小不一定为3。 实际上,在某些编译器中为4,如本在线演示中所示

补充说明

您可以使用标准类型uint8_t代替以双下划线开头的特定于编译器的类型名称。

关于对齐和大小主题,建议您谨慎使用内存布局假设。 我宁愿建议您的globalMem考虑使其成为其包含的所有结构的结构,以确保适当的对象语义并具有安全的布局。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM