如何确定/测量具有位字段的结构的大小?
#include <stdio.h>
typedef struct size
{
unsigned int a:1;
unsigned int b:31;
unsigned int c:1;
} mystruct;
int main()
{
mystruct a;
printf("%d", sizeof(a));
return 0;
}
- 使用
int b:31
时,输出为 8。 - 使用
int b:1
时,输出为 4。 - 使用
int b:32
时,输出 为输出是 12。
有人能解释一下原因吗?
#include <stdio.h>
typedef struct size
{
unsigned int a:1;
unsigned int b:31;
unsigned int c:1;
} mystruct;
int main()
{
mystruct a;
printf("%d", sizeof(a));
return 0;
}
- With
int b:31
, the output is 8. - With
int b:1
, the output is 4. - With
int b:32
, the output is 12.
Can somebody explain the reason for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
重要的是顺序。以下代码将给出输出: 8
Unsigned int 是一个 32 位整数,占用 4 个字节。内存在内存中是连续分配的。
选项 1:
输出:8
选项 2:
输出:12
选项 3:
输出:4
选项 4:
输出:8
It is the order that matters. The following code will give Output: 8
Unsigned int is a 32 bit integer, occupying 4 bytes. Memory is allocated contiguously in memory.
Option 1:
Output: 8
Option 2:
Output: 12
Option 3:
Output: 4
Option 4:
Output: 8
您没有说您是否知道位域是什么,但我假设您知道。
在你的实现中,显然
unsigned int
是一个32位整数,占用4个字节。这说明了第一个和第二个示例。显然,总共 33 位的 3 个位域不适合单个unsigned int
,因此第一个示例中需要 8 个字节。总共 3 位的 3 个位域确实适合一个unsigned int
,因此第二个示例中只有 4 个字节。此外,位域不能跨越多个整数。这就是第三个例子。我不记得这是标准的要求,还是只是实施的细节。无论哪种方式,由于
b
是 32 位,它会自行填充整个unsigned int
,从而强制a
和c< /code> 占据自己的
unsigned int
,前后中间一个。因此,为 12 个字节。You don't say whether you know what bitfields are, but I'll assume you do.
On your implementation, evidently
unsigned int
is a 32 bit integer, occupying 4 bytes. This accounts for the first and second examples. Clearly 3 bitfields totalling 33 bits don't fit into a singleunsigned int
, hence the need for 8 bytes in the first example. 3 bitfields totalling 3 bits certainly do fit into anunsigned int
, hence only 4 bytes in the second example.Furthermore, a bitfield cannot span multiple integers. This accounts for the third example. I can't remember whether that's a requirement of the standard, or just a detail of your implementation. Either way, since
b
is 32 bits, it fills a wholeunsigned int
on its own, forcing both ofa
andc
to occupy their ownunsigned int
, before and after the middle one. Hence, 12 bytes.根据史蒂夫·杰索普的回答只是为了通过添加一些可能有帮助的文档来完成他的回答。
——ISO/IEC 9899:201x 6.7.2.1
According to Steve jessop's answer just to fulfill his answer by adding some documents which may help.
——ISO/IEC 9899:201x 6.7.2.1
对齐
编译器将结构的大小舍入为 32 位,它可能尝试引用 32 位的每个对象的大小,同时它保留位字段的顺序。
因此,如果中间有一个 32 位项目,每一侧都有 1 位项目,则需要分配 3 个 32 位字,因此:12 个字节。
对于其他两种情况,问题只是您的位域序列可以打包到多少个 32 位对象中,同时仍保留字段顺序。
Alignment
The compiler is rounding the size of the structure to 32 bits, the size of each object it may try to reference to 32 bits, and at the same time it is preserving the order of your bit fields.
So if you have a 32-bit item in the middle and 1-bit items on each side, that's 3 32-bit words to allocate and so: 12 bytes.
For the other two cases, it's just a question of how few 32-bit objects your bitfield sequence can be packed into, while still preserving field order.