我想分配一些内存,将其初始化为某些值,然后将此内存的不同段转换为不同的结构。如下:
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
)并未真正正确分配/初始化
任何想法为什么这不起作用以及实现这样的事情的正确方法是什么?
谢谢!
答案 0 :(得分:0)
要实现您的目标,需要使用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
,这种赋值不尊重对象语义(因为不同globalMem
的内容除非您在代码中的某处使用placement new,否则地址不会初始化为正确的对象。
在使用此类技巧之前,您还可以确保structA
可以轻松复制(is_trivially_copyable<structA>::value
,幸运的是这里是真的)。
此外,由于globalMem
没有对齐约束,因此可能存在可能无法遵守的对齐约束的问题,但是根据编译器/体系结构,structA
可能需要字对齐。
最后,structA
的大小不一定是3,因为你倾向于思考。实际上在一些编译器上它将是4,如 this online demo
补充说明
您可以使用标准类型uint8_t
而不是以双下划线开头的编译器特定类型名称。
关于对齐和大小主题,我建议您对内存布局假设非常谨慎。我建议您globalMem
考虑将其作为所包含的所有结构的结构,以确保正确的对象语义并具有安全的布局。