c - 这个结构的大小是如何变成 4 字节的

标签 c bit-fields

我确实有一个包含位域的结构。根据我的说法,它是 2 个字节,但它是 4 个字节。我已经在 stackoverflow 上阅读了一些与此相关的问题,但无法与我的问题。这是我确实拥有的结构

struct s{
char b;
int c:8;
};
int main()
{
printf("sizeof struct s = %d bytes \n",sizeof(struct s));
return 0;
}

如果 int 类型必须在它的内存边界上,那么输出应该是 8 个字节但它显示 4 个字节??

最佳答案

enter image description here

来源:http://geeksforgeeks.org/?p=9705

总而言之:它在不影响对齐的情况下尽可能优化位打包(这就是位字段的含义)。

变量的数据对齐处理数据存储在这些库中的方式。比如int在32位机器上的自然对齐是4字节。当数据类型自然对齐时,CPU 会以最少的读取周期获取它。

同样,short int的自然对齐方式是2字节。这意味着,一个 short int 可以存储在 bank 0 - bank 1 对或 bank 2 - bank 3 对中。一个double需要8个字节,在内存库中占据两行。 double 的任何未对齐都将强制超过两个读取周期来获取 double 数据。

请注意,double 变量将分配在 32 位机器上的 8 字节边界上,并且需要两个内存读取周期。在 64 位机器上,根据 bank 的数量,double 变量将分配在 8 字节边界上,并且只需要一个内存读取周期。

所以编译器会对每个结构引入对齐要求。它将作为结构中最大的成员。如果您从 struct 中删除 char,您仍然会得到 4 个字节

在您的struct 中,char 是1 字节对齐的。它后面跟着一个 int 位域,它是 4 字节对齐的整数,但你定义了一个位域。

8 位 = 1 字节。 Char 可以是任何字节边界。所以 Char + Int:8 = 2 个字节。好吧,这是一个奇数字节边界,因此编译器会额外添加 2 个字节来维持 4 字节边界。

如果它是 8 个字节,您必须声明一个实际的 int(4 个字节)和一个 char(1 个字节)。那是5个字节。那是另一个奇怪的字节边界,所以 struct 被填充到 8 字节

我过去通常用来控制填充的方法是在我的 struct 之间放置填充符,以始终保持 4 字节边界。所以如果我有一个像这样的 struct:

struct s {
    int id;
    char b;
};

我将按如下方式插入分配:

struct d {
    int id;
    char b;
    char temp[3];
}

这将给我一个大小为 4 字节 + 1 字节 + 3 字节 = 8 字节的 struct!这样我可以确保我的 struct 以我想要的方式填充,尤其是当我通过网络将它传输到某个地方时。另外,如果我改变了我的实现(例如,如果我可能将这个 struct 保存到一个 binary 文件中,填充符从一开始就在那里,只要我保持我的初始结构,一切都很好!)

最后,你可以在C Structure size with bit-fields上阅读这篇文章以获得更多解释。

关于c - 这个结构的大小是如何变成 4 字节的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7121408/

相关文章:

c++ - Windows 中的网络文件传输

用C计算文件中的单词

c++ - C 和 C++ 中 WINAPI 的区别

只清除结构的位域成员?

c - 请澄清我对 C 中位域和 union 的理解

c - fprintf 在使用 Make 编译的 C 程序中不起作用

c - C 数组中的查询

c - 如何一起处理位域和 qsorting?

c++ - C++结构中的位字段声明

c++ - 结构中的位顺序不是我所期望的