C中内存对齐原则

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiong452980729/article/details/70140050

C中内存对齐原则

原则:
1.结构体内成员按自身按自身长度自对齐。
自身长度,如char=1,short=2,int=4,double=8,。所谓自对齐,指的是该成员的起始位置的内存地址必须是它自身长度的整数倍。如int只能以0,4,8这类的地址开始
2.结构体的总大小为结构体的有效对齐值的整数倍


结构体的有效对齐值的确定:
1)当未明确指定时,以结构体中最长的成员的长度为其有效值
2)当用#pragma pack(n)指定时,以n和结构体中最长的成员的长度中较小者为其值。
3)当用__attribute__ ((__packed__))指定长度时,强制按照此值为结构体的有效对齐值


eg:
struct AA{
    char a;
    int b;
    char c; 
}aa;
sizeof(aa)=12

假设结构体内存起始地址为0,则地址的分布如下
0  a
1  
2
3
4  b(自对齐)
5  b
6  b
7  b
8  c
9
10
11
char的字对齐长度为1,所以可以在任何地址开始,但是,int自对齐长度为4,必须以4的倍数地址开始。所以,尽管1-3空着,但b也只能从4开始。再加上c后,整个结构体的总长度为9,结构体的有效对齐值为其中最大的成员即int的长度4,所以,结构体的大小向上扩展到12,即9-11的地址空着。


struct AA{
    char a;
    char c; 
    int b;    
}aa;
sizeof(aa)=8

0  a
1  c(自对齐)
2
3
4  b(自对齐)
5  b
6  b
7  b
因为c为char类型,字对齐长度为1,所以可以有效的利用1-3间的空格。看见了吧,变量定义的位置的不同时有可能影响结构体的大小的哦!


#pragma pack(2)
struct AA{
    char a;
    int b;
    char c; 
}aa;
sizeof(aa)=10

a到c只占9字节长度,因为结构体的有效对齐长度在pack指定的2和int的4中取较小的值2。故取2的倍数10。如果当pack指定为8呢?那就仍然按4来对齐,结果仍然是12。


struct AA{
    char a;
    int b;
    char c; 
}__attribute__((__8__))aa;
sizeof(aa)=16

其实a到c仍然只占9字节长度,但结构体以8对齐,故取8的倍数16.如果其指定2,则结果为10

如果pragma pack和__attribute__同时指定则以__attribute__ 的为准。
需要说明的是,不管pragma pack和__attribute__如何指定,结构体内部成员的自对齐仍然按照其自身的对齐值。

展开阅读全文

没有更多推荐了,返回首页