---
# System prepended metadata

title: 有趣的memory alignment
tags: [C]

---

# 有趣的memory alignment
* R5-2600, 32GB, ubuntu 24.04 LTS(64bits), gcc-13

```c
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))
```c
struct __attribute__((packed)) PackedData {
    unsigned int : 3;  // 3 位元填充
    unsigned int f1 : 1;
    unsigned int f2 : 2;
    unsigned int f3 : 1;
    unsigned int f4 : 1;
};
```
2. 使用#pragma pack(1)
```c
#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()
```
3. 更改基底為unsigned char
```c
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的，需要特別注意
```c
int main() {
    struct PackedData data = {0};
    data.f1 = 2;  // Overflow!

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