为什么使用 24 位整数时结构大小不会改变
why size of structure does not change when use 24 bit integer
我正在尝试在Windows平台中移植嵌入代码。 我遇到了以下问题,我在这里发布示例代码。 即使在我使用 int24 之后,这里的大小在 Windows 中仍然是 12 字节,为什么?
struct INT24
{
INT32 data : 24;
};
struct myStruct
{
INT32 a;
INT32 b;
INT24 c;
};
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char myArr[11] = { 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF };
myStruct *p = (myStruct*)myArr;
cout << sizeof(*p);
}
有两个原因,每个原因本身就足够了。
- 据推测,
INT32
的大小为 4 个字节。INT24
的大小也是 4 个字节,因为它包含一个INT32
位字段。由于myStruct
包含 3 个大小为 4 的成员,因此其大小必须至少为 12。 - 据推测,
INT32
的对齐要求是 4。因此,即使INT24
的大小为 3,myStruct
的大小仍必须为 12,因为它必须至少具有INT32
的对齐要求,因此myStruct
的大小必须填充到最接近的 4 的倍数。
任何方法或解决方法?
这是特定于实现的,但以下技巧可能适用于某些编译器/CPU 组合。有关类似功能的语法,请参阅编译器手册,以及目标 CPU 是否支持未对齐的内存访问的手册。还要意识到未对齐的内存访问确实会降低性能。
#pragma pack(push, 1)
struct INT24
{
INT32 data : 24;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct myStruct
{
INT32 a;
INT32 b;
INT24 c;
};
#pragma pack(pop)
打包位字段可能不是在所有编译器中都相同。请务必检查您的行为。
我认为一种标准的兼容方法是存储大小为 3 和 4 的 char 数组,每当您需要读取或写入其中一个整数时,您都必须std::memcpy
该值。实施起来会有点麻烦,也可能比 #pragma 包黑客慢。
可悲的是,编译器在优化特定体系结构的代码时保留通过在成员之间甚至在结构末尾插入空格来填充结构的权利。
使用位字段不会减小struct
的大小;您仍然可以在struct
中获得整个"fielded"类型。
该标准保证struct
的第一个成员的地址与struct
的地址相同,除非它是多态类型。
但一切都不会丢失:您可以依靠这样一个事实,即char
数组将始终是连续的并且不包含包装。
如果系统上将CHAR_BIT定义为 8(可能是),则可以在char
数组上对 24 位类型的数组进行建模。如果不是 8,那么即使这种方法也行不通:然后我建议诉诸内联汇编。
相关文章:
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 当我使用CHAR_INFO结构时,控制台会无缘无故地改变颜色
- 为什么?在改变构建结构后,可执行文件的大小显著减少
- 为什么使用 24 位整数时结构大小不会改变
- 为什么结构数组的内存集会改变程序行为
- 修改 std::vector 的底层数据结构不会改变其大小
- 将一个结构复制到另一个结构以及改变一个结构对另一个结构的影响
- 读取和写入结构到二进制文件,如果结构已经改变
- 使用Boost,如何在类层次结构改变后反序列化c++类
- 是否有任何优化选项,可以改变结构的对齐在VS2012
- 在c++中调用time会改变我的结构体tm
- 如何改变Rcpp函数中R结构的值