【问题标题】:memory layout of bitfield in C - can't understand the outputC中位域的内存布局 - 无法理解输出
【发布时间】:2014-11-10 10:51:00
【问题描述】:

我有这个代码 - http://ideone.com/sXhWxf

#include <stdio.h>

int main(void) {

struct bitfield{
    unsigned a:5;
    unsigned c:5;
    unsigned b:6;
} bit = {1,3,3};

char *p = (char*)&bit;
printf("%d\n",*p);
p++;
printf("%d\n",*p);
// I assumed that the bits are laid out in the below order in the memory.
// Spaces are just for clarity
// 00001 00011 000011
// Also, I asumed that the 'char' will take 8 bits. But I can't understand output.
// According to me the output should be - 8 195 (considering the 1st 8 bits & 
// last eight bits for the printf statements)
return 0;

}

输出是 -

97
12

谁能帮我详细理解这个输出? (请阅读代码中的cmets)

另外,我在Wikipedia 上看到了这个声明,它说“位域的成员没有地址,因此不能与地址-of (&) 一元运算符一起使用。sizeof 运算符可能不适用于位字段。" 但我可以访问 'bit' 变量的地址。那个怎么样?我没有正确解释该声明吗?请指导我。

【问题讨论】:

    标签: c++ c memory output bit-fields


    【解决方案1】:

    假设你的目标机器上的整数是 32 位的,编译器会这样布置bit 结构:

    bit 31                            bit 0
    |                                 |
    xxxxxxxxxxxxxxxx bbbbbb ccccc aaaaa
    

    x 位未使用。

    有了a=1, c=3, b=3,这就变成了

    0000000000000000 000011 00011 00001
    

    分割成字节:

    00000000 00000000 00001100 01100001
    

    十进制:

    0 0 12 97
    

    当存储为 little-endian 整数时,字节顺序为 97 12 0 0,这解释了您的输出。

    至于你的第二个问题:你正在获取bit 结构的地址,而不是它的任何位域。 char *p = (char*)&amp;bit.a; 不起作用。

    【讨论】:

      【解决方案2】:

      您正在尝试访问结构的地址而不是位域,这就是为什么您能够访问 char p = (char)&bit;

      你不能做这样的事情 char p = (char)&(bit.a);

      现在进入正题:

      不建议使用地址访问位域,因为位域在内存中的打包取决于很多参数。

      【讨论】:

        【解决方案3】:

        借用此处的另一个答案 (Memory layout of struct having bitfields),C 规范不对位域的顺序做出任何保证:

        一个实现可以分配任何大到足以容纳位域的可寻址存储单元。如果有足够的空间剩余,紧跟在结构中另一个位域之后的位域将被打包到同一单元的相邻位中。如果剩余空间不足,则将不适合的位域放入下一个单元还是与相邻单元重叠是实现定义的。单元内位域的分配顺序(高位到低位或低位到高位)由实现定义。

        在这种情况下,让我们看看您的示例的输出。

        97 转换为 01100001。如果我们分开,我们可以看到我们的成员为 ...011 00001。12 转换为 000011 00,它构成了我们数据结构的其余部分。正如您所假设的,编译器已将每个变量首先打包到内存最低位而不是最高位。

        由于这是实现定义的,因此不建议使用它,除非您确切知道编译器将如何处理代码。

        有关更多信息和示例,请参见此处:C/C++: Force Bit Field Order and Alignment

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-23
          • 2018-04-28
          • 2016-04-11
          • 2020-11-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多