一、前言
每一个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。GCC中默认#program pack(4),即4个字节的内存对齐。Keil也是采用4字节对齐的。也可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这一系数,一般情况下尽量使用自然对齐系数,不要修改它。
STM32单片机上各个变量占用的字节数:
二、公式
公式一、结构体变量里,成员的起始地址必须满足 : 起始地址 % 成员的字节数(sizeof值)= 0 (说白了就是能整除)
公式二、结构体变量的总字节数必须满足:总字节数 % 最大的成员字节数 = 0 (说白了就是能整除)
2.1、例子一
struct te_a{
char a;
int b;
char c;
}Test1;
OK,经过公式一的运算后,结构体里成员的分布如下:
经过公式一的计算后,结构体变量Test1的大小是9个字节。内存对齐的计算还没有结束,接着使用公式二计算:
结构体变量的总字节数 % 最大的成员字节数 = 0 , 在结构体变量Test1里,最大的成员是b,b的大小是4个字节。那么,当前的结构体变量大小9字节 % 4字节 等于 0 。当结构体变量大小为12字节 % 4字节 = 0,所以最终结构体变量Test1占用的内存字节数是12,其内存的分布如下:
以上的都是根据公式计算出来的结果,那实际在单片机里是不是这样呢?把代码下载到STM32单片机里,进入DEBUG模式看看。
从以下的内存分布看来,公式一与公式二的计算没有问题。
2.2、例子二
struct te_a{
int a;
float b;
char c;
}Test1;
OK,经过公式一的运算后,结构体里成员应该占用9个字节的内存,内存的分布如下:
接着根据公式二的运算,结构体的总字节数 % 最大的成员字节数 = 0, 可以轻松得出结构体的总字节数 = 12时,满足12 % 4 = 0。所以经过公式二的计算后,内存分布如下:
把代码烧录到STM32,进入Debug模式看看。
2.3、例子三
struct te_a{
int a;
float b;
double c;
}Test1;
OK,经过公式一的运算后,结构体里成员应该占用16个字节的内存,内存的分布如下:
接着根据公式二的运算,结构体的总字节数 % 最大的成员字节数 = 0, 那么16 % 8 = 0,运气非常好,公式二不用补位就能让公式二成立。所以经过公式二的运算后,内存还是一样的:
把代码烧录到STM32,进入Debug模式看看。
总结
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注编程网的更多内容!