结构体&&内存对齐总结

结构体内存究竟是怎样分布的呢,

对于以前在访问stm32内部flash时,对于访问的问题做如下总结:

关键字词:寻址(字节,位,半字节);

内存对齐:初始地址的选择不是任意的,必须是寻址单位的整数倍,否则会出现各种内存的读写错误,不是数据不正确,或者莫名其妙的程序崩溃等等问题。

关于结构体变量类型之间的强制转换:

https://blog.csdn.net/nethanhan/article/details/10058459

点(.)是用于结构体变量访问成员,箭头(->)是用于结构体指针访问成员。

1
2
3
4
5
6
7
struct  str1
     {
         char  a;
         int  b;
         float  c;
         double  d;
     };

str1这个结构体占用的内存是多少呢?如果用变量类型直接想加,得到的结果是17,但显然不是这样的。这个程序运行的正确结果是24.为什么呢?

  因为为了CPU能够快速访问,提高访问效率,变量的起始地址应该具有某些特性,这就是所谓的“对齐”。比如4字节的int型变量,那它的起始地址就应该在4字节的边界上,即起始地址可以被4整除。

  内存对齐的规则:

  1.起始地址为该变量类型所占内存的整数倍,若不足则不足部分用数据填充至所占内存的整数倍。

  2.该结构体所占总内存为结构体成员变量中最大数据类型的整数倍。

  接下来我们分析上面的例子:

  char型变量占一个字节,所以它的起始地址为0,而int类型占4个字节,它的起始地址应该是4(的整数倍),那么内存地址1、2、3就需要被填充。同样,float占用4个字节,而结构体中a,b两个成员变量占了0~7内存地址,c的地址从8开始,符合规则一,占用内存地址为8~11。double类型占8个字节,所以d的起始地址就应该从16开始,那么12、13、14、15内存地址就需要被填充。d从16地址开始,占用8个字节。整个结构体占用字节数为24,符合规则二。内存分配如图:红色区域为填充部分

下面再举一个例子,进一步说明:

 

1
2
3
4
5
6
7
struct str2
    {
        double a;
        int b;
        char c;
        double d;
    };

str2这个结构体占用的内存空间是多少呢?是24!怎么分析呢?

首先double类型的a占用内存地址为0~7,int类型的b起始地址为8,符合规则一,占用地址为8~11,char类型的c占一个字节,地址为12.那么double类型的d,起始地址为13吗?显然不是,满足规则一的地址是16,所以d起始地址为16,占用16~23。结构体总共24个字节,满足规则二。如果这个结构体最后再加一个成员变量 char e,那这个结构体占用的内存是多少?char类型的e起始地址为24,占用地址为24,但是结构体一种有25个字节,就不满足规则二了,怎么办呢?为了满足规则二,我们将25~31进行填充,因此整个结构体占用32个字节。

这就是结构体内存占用问题的分析方法。由于水平有限,有什么问题希望读者不吝赐教!


猜你喜欢

转载自blog.csdn.net/qq_39491794/article/details/79999787