结构体struct内存对齐

原因:

结构体内存对齐是因为,对于计算机来说读取4个字节的内存空间比读取1、2、3个字节的要更高效。但是也根据编译器而定,而且自己也可以改变对齐内存的大小用 预编译命令#pragma pack (n)
 

规则:

1.第一个元素offset偏移到地址为0的内存上。

2.之后的元素对齐到对齐数大小的整数倍的偏移量上。

何为对齐数:对齐系数和元素大小的较小值,每个成员变量除了第一个成员都有对齐数

3.结构体整体对象的大小必须是最大对齐数的整数倍。

4.结构体内含有结构体也按该结构体的大小计算对齐数。

 

#include <iostream>

using namespace std;

struct A {
    int a; // 4
    int b; // 4
    char c; // 1
}; // 12

struct B {
    bool a; // 1
    bool b; // 1
}; // 2

struct C {
    char A; // 1
    bool b; // 1
}; // 2

// 这块要注意了,是对于最大对齐数的整数倍,虽然结构体A大小是12,但是12和对齐系数相比较,对齐系数4较小,这个结构体的对齐数为4
struct D {
    struct A a; // 12
    int b; // 4
    char c; // 1
}; // 24

struct E {
    int b;
    char c;
    struct A a;
};

// 而且对齐系数的预编译作用范围在该命令之后,之前的数据并不影响
#pragma pack (2)
struct F {
    int a;
    int b;
    char c;
};

// 这里也要注意,还是对齐数的问题,char是1,对齐系数是2,应该用1对齐,故还是三是1的倍数。
struct G {
    char a;
    char b;
    char c;
};

#pragma pack (4)

// 指针变量的大小是4
// 而且这里太有趣了,内存对齐只在预编译之后进行,甚至可以放在结构体内部进行,说明结构体的内存申请不是都读取完再申请,而是按顺序执行再申请
struct H {
    int *a;
    #pragma pack (2)
    char c;
};

#pragma pack (4)
struct I {
    int *a;
    int c : 64;
};

struct J {
    int a : 16;
    int : 100; // 用来设置空位,即前四个字节之后的16个字节为空,不使用。但是也算在结构体内存里 ceil(100 / 8)
    int c;
};

int main () {

cout << sizeof (struct A) << endl;
cout << sizeof (struct B) << endl;
cout << sizeof (struct C) << endl;
cout << sizeof (struct D) << endl;
cout << sizeof (struct E) << endl;
cout << sizeof (struct F) << endl;
cout << sizeof (struct G) << endl;
cout << sizeof (struct H) << endl;
cout << sizeof (struct I) << endl;
cout << sizeof (struct J) << endl;

    return 1;
}

大家同时也可以看到,在结构体中的元素里后面加冒号的情况,这代表位域。表示我让某个元素一定要占有多少位。也可以不写变量名,只写变量的位域,表示这段空间不存内容但是要空闲出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值