结构体存储对齐

转载来自:http://www.cnblogs.com/longlybits/articles/2385343.html

结构体存储对齐

许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,要求这些数据的起始地址的值是某个数的倍数,这就是所谓的内存对齐;
在不对齐的数据存取时候,对于小数据的访问会影响其效率,对齐即是多分配一些字节,填充无用数据,以空间的损失来换取效率。
win32平台下的微软C编译器对齐策略:
1)结构体变量的首地址能够被其最宽数据类型成员的大小整除。编译器在为结构体变量开辟空间时,首先找到结构体中最宽的数据类型,然后寻找内存地址能被该数据类型大小整除的位置,这个位置作为结构体变量的首地址。而将最宽数据类型的大小作为对齐标准。
2)结构体每个成员相对结构体首地址的偏移量(offset)都是每个成员本身大小的整数倍,如有需要会在成员之间填充字节。编译器在为结构体成员开辟空 间时,首先检查预开辟空间的地址相对于结构体首地址的偏移量是否为该成员大小的整数倍,若是,则存放该成员;若不是,则填充若干字节,以达到整数倍的要求。
3)结构体变量所占空间的大小必定是最宽数据类型大小的整数倍。如有需要会在最后一个成员末尾填充若干字节使得所占空间大小是最宽数据类型大小的整数倍。
sizeof对结构体大小计算举例:
1.test1:空结构体

typedef struct node1
{     
}S1;

在C++中:sizeof(S1)=1;
在C中:sizeof(S1)=0;
2.test2:

typedef struct node2
{
    int a;
    char b;
    short c;
}S2;

则sizeof(S2)=8。结构体S2中最长的数据类型是int占4个字节,因此以4字节对齐,则该结构体在内存中存放方式为:
|——-int——-| 4字节
|char|—-|-short-| 4字节
总共占8字节
3.test3:含有静态数据成员

typedef struct node3
{
    int a;
    short b;
    static int c;
}S3;

则sizeof(S3)=8。这里结构体中包含静态数据成员,而静态数据成员c是单独存放在静态数据区的(只有在C++结构体中才能含有静态数据成员,C结构体中是不允许含有静态数据成员的)。其在内存中存储方式如下:
|——-int——-| 4字节
|–short-|—-|—-| 4字节
4.test4:结构体中含有结构体

typedef struct node4
{
    bool a;
    S1 s1;
    short b;
}S4;

则sizeof(S4)=16。s1占8字节,而s1中最长数据类型为int占4个字节,bool类型1个字节,short占2字节,因此以4字节对齐,则存储方式为
|——-bool——-| 4字节
|——–s1——–| 8字节
|——-short——| 4字节
5.test5:

typedef struct node5
{
    bool a;
    S1 s1;
    double b;
    int c;
}S5;

则sizeof(S5)=32。s1占8字节,而s1中最长数据类型int占4字节,而double占8字节,因此以8字节对齐,则存放方式为:
|——-bool——-| 8字节
|——–s1——–| 8字节
|——double—–| 8字节
|—-int—-|——-| 8字节
6.test6:
若在程序中使用了#pragma pack(n)命令强制以n字节对齐时,默认情况下n为8;
则比较n和结构体中最长数据类型所占的字节大小,取两者中小的一个作为对齐标准;
若需取消强制对齐方式,则可用命令#pragma pack();
如果在程序开头使用命令#pragma pack(4),对于上面test5中的结构体S5
sizeof(S6)=24。因为强制以4字节对齐,而S6中最长数据类型double占8字节,因此以4字节对齐。在内存中存放方式为:
|——-a——-| 4字节
|——-s1——| 4字节
|——-s1——| 4字节
|——-b——-| 4字节
|——-b——-| 4字节
|——-c——-| 4字节
So,以后在定义结构体时最好将成员变量按大小顺序排列定义,以节省空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值