包含位字段的结构的大小
size of a structure containing bit fields
可能的重复:
为什么不是';t结构的sizeof等于每个成员的sizeof之和?
我试图理解位字段的概念。但我不知道为什么CASE III中以下结构的大小是8字节。
情况I:
struct B
{
unsigned char c; // +8 bits
} b;
大小(b);//输出:1(因为无符号字符在我的系统上占用1个字节)
情况II:
struct B
{
unsigned b: 1;
} b;
sizeof(b); // Output: 4 (because unsigned takes 4 bytes on my system)
情况III:
struct B
{
unsigned char c; // +8 bits
unsigned b: 1; // +1 bit
} b;
sizeof(b); // Output: 8
我不明白为什么案例III的输出是8。我期望1(char)+4(unsigned)=5。
您可以使用offsetof
检查结构的布局,但它将是以下行的内容:
struct B
{
unsigned char c; // +8 bits
unsigned char pad[3]; //padding
unsigned int bint; //your b:1 will be the first byte of this one
} b;
现在,很明显(在32位拱门中)sizeof(b)
将是8
,不是吗?
问题是,为什么有3个字节的填充,而不是更多或更少?
答案是,结构中字段的偏移与字段本身的类型具有相同的对齐要求。在您的体系结构中,整数是4位对齐的,因此offsetof(b, bint)
必须是4的倍数。它不能是0,因为之前有c
,所以它将是4。如果字段bint
从偏移量4开始,长度为4字节,则结构体的大小为8。
另一种方法是,结构的对齐要求是其任何字段中最大的,因此该B
将是4位对齐的(因为它是您的位字段)。但一个类型的大小必须是对齐的倍数,4是不够的,所以它将是8。
我认为您在这里看到了对齐效果。
许多体系结构要求整数存储在存储器中的地址,该地址是字大小的倍数。
这就是为什么第三个结构中的char被填充了三个字节,这样下面的无符号整数就从一个单词大小的倍数的地址开始。
Char根据定义是一个字节。int在32位系统上是4个字节。并且该结构被填充了额外的4。
请参阅http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86关于填充的一些解释
为了保持对内存的访问对齐,编译器正在添加填充。如果您打包结构,它将不会添加填充。
我又看了一眼,下面是我的发现。
- 在C书中,"几乎所有关于字段的内容都依赖于实现。">
- 在我的机器上:
struct B { unsigned c: 8; unsigned b: 1; }b; printf("%lun", sizeof(b));
打印4,这是一个短;
您将位字段与常规结构元素混合在一起。
顺便说一句,位字段被定义为:"在一个sindle实现定义的存储单元内的一组相邻的位"所以,我甚至不确定":8"是否符合您的要求。这似乎不符合比特字段的精神(因为它不再是一点了)
结构的对齐方式和总大小是特定于平台和编译器的。在这里,你不能不期待直截了当和可预测的答案。编译器总是有一些特别的想法。例如:
struct B
{
unsigned b0: 1; // +1 bit
unsigned char c; // +8 bits
unsigned b1: 1; // +1 bit
};
编译器可以将字段b0和b1合并为一个整数,也可以不合并。这取决于编译器。有些编译器具有控制此操作的命令行键,而有些编译器则没有。其他示例:
struct B
{
unsigned short c, d, e;
};
由编译器来打包/不打包这个结构的字段(一个32位的平台)。结构的布局在DEBUG和RELEASE版本之间可能有所不同。
我建议只使用以下模式:
struct B
{
unsigned b0: 1;
unsigned b1: 7;
unsigned b2: 2;
};
当你有一系列共享相同类型的位字段时,编译器会把它们放在一个int中。否则,各个方面都会发挥作用。还要考虑到,在一个大项目中,你写一段代码,其他人会写并重写makefile;将代码从一个dll移动到另一个dll。此时将设置并更改编译器标志。99%的可能性是这些人不知道你的结构的对齐要求。他们甚至永远不会打开你的文件。
- 结构包含在两个头文件中,这两个文件我都不拥有
- ctypes - 结构包含垃圾/不正确的数据
- 在node-gip binding.gyp文件中,如何根据系统结构(32位、64位)包含不同的库文件
- 结构包含对自我或其他结构类型的引用
- 可以结构包含参数
- 将包含位字段和动态数据的结构复制到 Char 数组缓冲区中
- 序列化python类与C型结构(带有位式结构)以发送插座
- 如何实现 std::map::查找包含两个结构'Pos'结构的比较逻辑,每个结构包含 x 和 y 坐标
- C 如何从UCHAR数组中填充结构的位字段
- 结构中位字段的用是什么
- 包含位字段的结构的大小
- 如何对结构进行位操作
- 结构/类位字段打包
- 将包含位的字符串转换为矢量<bool>
- c++如何将结构包含向量
- 封送结构(包含数组)作为返回值
- 已分配结构包含向量的内存泄漏
- 如何检查llvm callInst是否包含位转换
- 为什么Char*的长度= 1时,结构包含vector使用memcpy复制到它.我们有其他方法吗?
- 需要结构包含/实现帮助(pt 2)C++