结构体内存的对齐方式

Posted 创世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结构体内存的对齐方式相关的知识,希望对你有一定的参考价值。

STM32中  

INT为 4字节

 

short  int 为2字节

 

 

 

 

结构体内存对齐规则

结构体所占用的内存与其成员在结构体中的声明顺序有关,其成员的内存对齐规则如下:

(1)每个成员分别按自己的对齐字节数和PPB(指定的对齐字节数,32位机默认为4)两个字节数最小的那个对齐,这样可以最小化长度。

(2)复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。

(3)结构体对齐后的长度必须是成员中最大的对齐参数(PPB)的整数倍,这样在处理数组时可以保证每一项都边界对齐。

(4)计算结构体的内存大小时,应该列出每个成员的偏移地址,则其长度=最后一个成员的偏移地址+最后一个成员数的长度+最后一个成员的调整参数(考虑PPB)。

下面举例说明上述规则:

复制代码
#include
#pragma pack(2) //指定PPB为2
struct T{
char a; //偏移地址0
int b; //偏移地址2
char c; //偏移地址6
};

#pragma pack() //恢复原来默认PPB,32位下为4

int main(int argc,char * argv[])
{
printf("sizeof(struct T));
return 0;
}
复制代码

最后输出的结果为:8。语句#pragma pack(2)的作用是指定结构体按2字节对齐,即PPB=2。分析如下:

变量a默认为1字节,PB=2,所以a按1字节对齐,a的偏移地址为0。

变量b默认为4字节(在32位机器中int为4字节),PB=2,所以b按2字节对齐,b的偏移地址为2。

变量c默认为1字节,PB=2,所以c按1字节对齐,偏移地址为6。

此时结构体的计算出的字节数为7个字节。最后按规则3,结构体对齐后的字节数为8。sizeof(T)=6+1+1=8

图解:

 

3.范例

(1)#pragma pack(2) //指定PPB为2

struct T{
char a; //偏移地址0
char b; //偏移地址1
int c; //偏移地址2
};

则sizeof(T)=最后一个成员的偏移地址+最后一个成员数的长度=2+4=6。

(2)

复制代码
struct T1{
char a; //偏移地址0
char b; //偏移地址1
int c; //偏移地址4
};

struct T2{
char a; //偏移地址0
int b; //偏移地址4
char c; //偏移地址8
};
复制代码

PPB=4,则sizeof(T1)=4+4=8;sizeof(T2)=8+1=9,9不能整除4,故调整数为3,即sizeof(T2)=8+1+3=12

4.注意的问题

(1)字节对齐取决于编译器;

(2)一定要注意PPB大小,PPB大小由pragam pack(n)指定;

(3)结构体占用的字节数要能被PPB整除。

 

以上是关于结构体内存的对齐方式的主要内容,如果未能解决你的问题,请参考以下文章

[.NET] 结构体布局详解与结构体内存对齐具体方式

结构体内存的对齐方式

结构体在内存中的存储方式

结构体内存对齐

关于结构体内存对齐方式的总结(#pragma pack()和alignas())

C++ 结构体对齐