[英]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,但没有得到任何编译器错误,但似乎我的变量( a1
, a2
和b1
)并未真正正确地分配/初始化。
是否知道为什么这样不起作用以及实现这样的正确方法的任何想法?
谢谢!
要实现您打算做的事情,需要使用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.