Try   HackMD

有趣的memory alignment

  • R5-2600, 32GB, ubuntu 24.04 LTS(64bits), gcc-13
struct PackedData {
    unsigned int : 3;  // 3 位元填充
    unsigned int f1 : 1;
    unsigned int f2 : 2;
    unsigned int f3 : 1;
    unsigned int f4 : 1;
};

int main(void){
    printf("size: %zu\n", sizeof(sturct PackedData));
    return 0;
}

會返回4Bytes,推測為編譯器在編譯時還是會以unsigned int為基底,如果想要讓編譯器強制根據Bit-padding佈局,可以使用以下幾種方法

  1. 使用__attribute__((packed))
struct __attribute__((packed)) PackedData {
    unsigned int : 3;  // 3 位元填充
    unsigned int f1 : 1;
    unsigned int f2 : 2;
    unsigned int f3 : 1;
    unsigned int f4 : 1;
};
  1. 使用#pragma pack(1)
#pragma pack(1)
struct PackedData {
    unsigned int : 3;
    unsigned int f1 : 1;
    unsigned int f2 : 2;
    unsigned int f3 : 1;
    unsigned int f4 : 1;
};
#pragma pack()
  1. 更改基底為unsigned char
struct PackedData {
    unsigned char : 3;  // 3 位元填充
    unsigned char f1 : 1;
    unsigned char f2 : 2;
    unsigned char f3 : 1;
    unsigned char f4 : 1;
};

都會返回PackedData為1Byte
另外更改Bit padding來符合memory alignment如果存入超過指定大小的data也是會發生overflow的,需要特別注意

int main() {
    struct PackedData data = {0};
    data.f1 = 2;  // Overflow!

    printf("f1: %u\n", data.f1);  // 查看溢位後的結果
    return 0;
}