size of a structure containing bit fields
Possible Duplicate:
Why isn't sizeof for a struct equal to the sum of sizeof of each member?
我试图理解位场的概念。但我不明白为什么在第三种情况下,下面的结构的大小是8字节。
案例一:1 2 3 4 | struct B { unsigned char c; // +8 bits } b; |
sizeof(b);//输出:1(因为无符号字符在我的系统上占用1个字节)
案例二:1 2 3 4 5 6 | struct B { unsigned b: 1; } b; sizeof(b); // Output: 4 (because unsigned takes 4 bytes on my system) |
III案:
1 2 3 4 5 6 7 | struct B { unsigned char c; // +8 bits unsigned b: 1; // +1 bit } b; sizeof(b); // Output: 8 |
我不明白为什么案例三的输出是8。我期待着1(char)+4(unsigned)=5。
您可以使用
1 2 3 4 5 6 | 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位的拱门中)
问题是,为什么要填充3个字节,而不是更多或更少?
答案是,字段到结构的偏移量与字段本身的类型具有相同的对齐要求。在您的体系结构中,整数是4字节对齐的,所以
另一种看它的方法是,结构的对齐要求是它的任何字段中最大的,所以这个
我想你在这里看到了一个对齐效果。
许多体系结构要求将整数存储在内存中的多个字大小的地址中。
这就是为什么第三个结构中的char被另外三个字节填充,以便下面的无符号整数从一个单词大小的倍数地址开始。
字符的定义是一个字节。整数是32位系统上的4个字节。结构正在被额外的4个填充。
有关填充的一些解释,请参见http://en.wikipedia.org/wiki/data_-structure_-alignment典型的_-c-structs_-on-x86
我又看了一眼,这是我发现的。
1
2
3
4
5
6 struct B {
unsigned c: 8;
unsigned b: 1;
}b;
printf("%lu
", sizeof(b));
打印4,简称4;
您正在将位字段与常规结构元素混合。
顺便说一句,位字段定义为:"Sindle实现中的一组相邻位定义了存储单元",因此,我甚至不确定":8"是否满足您的需要。这似乎不符合比特场的精神(因为它不再是比特场了)
结构的对齐方式和总大小是平台和编译器特有的。在这里,你不可能期望得到直接而可预测的答案。编译器总是有一些特殊的想法。例如:
1 2 3 4 5 6 | struct B { unsigned b0: 1; // +1 bit unsigned char c; // +8 bits unsigned b1: 1; // +1 bit }; |
编译器可以将字段b0和b1合并为一个整数,但不能合并。这取决于编译器。有些编译器有控制这个的命令行键,有些编译器没有。其他例子:
1 2 3 4 | struct B { unsigned short c, d, e; }; |
由编译器来打包/不打包这个结构的字段(即32位平台)。结构的布局在调试和发布版本之间可能有所不同。
我建议只使用以下模式:
1 2 3 4 5 6 | struct B { unsigned b0: 1; unsigned b1: 7; unsigned b2: 2; }; |
当您有共享同一类型的位字段序列时,编译器会将它们放入一个int中,否则各个方面都会起作用。还要考虑到,在一个大型项目中,您编写一段代码,其他人将编写和重写makefile;将代码从一个dll移动到另一个dll。此时将设置和更改编译器标志。99%的人可能不知道您的结构的对齐要求。他们甚至不会打开你的文件。
为了保持对内存的访问保持一致,编译器正在添加填充。如果对结构进行打包,它将不会添加填充。