经典的sizeof(struct)和sizeof(union)内存对齐

内存对齐作用:

1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某 些地址处取某些特定类型的数据,否则抛出硬件异常。

2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存, 处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

结构体struct内存对齐的3大规则:

1.对于结构体的各个成员,第一个成员的偏移量是0,排列在后面的成员其当前偏移量必须是当前成员类 型的整数倍;

2.结构体内所有数据成员各自内存对齐后,结构体本身还要进行一次内存对齐,保证整个结构体占用,内存大小是结构体内最大数据成员的最小整数倍;

3.如程序中有#pragma pack(n)预编译指令,则所有成员对齐以n字节为准(即偏移量是n的整数倍),不再 考虑当前类型以及最大结构体内类型。

#pragma pack(1)    //32位默认4个字节一个空间。 这里可以是最少空间可以是1的倍数因为用了
struct fun
{
    int i;         |x|x|x|x|
    double d;      |x|x|x|x|x|x|x|x|
    char c;        |x|
};




 sizeof(fun) = 13

struct CAT_s   //这里空间可以是4的倍数
{
    int ld;              // 4    |x|x|x|x|
    char Color;          // 1    
    unsigned short Age;  // 2    |x|0|x|x|     //这是char和short共用四个空间
    char *Name;          // 4    |x|x|x|x|
    void(*Jump)(void);   // 4    |x|x|x|x|
}Garfield;
  •  1.使用32位编译,int占4, char 占1, unsigned short 占2,char* 占4,函数指针占4个,由于是32位 编译是4字节对齐,所以该结构体占16个字节。(说明:按几字节对齐,是根据结构体的最长类型决定 的,这里是int是最长的字节,所以按4字节对齐);
  • 2.使用64位编译 ,int占4, char 占1, unsigned short 占2,char* 占8,函数指针占8个,由于是64位 编译是8字节对齐(说明:按几字节对齐,是根据结构体的最长类型决定的,这里是函数指针是最长的字 节,所以按8字节对齐)所以该结构体占24个字节。

struct C       //空间要是8的倍数
{
    double t; //8      |x|x|x|x|x|x|x|x|
    char b;   //1      
    int a;    //4      |x|0|0|0|x|x|x|x|
    short c;  //2      |x|x|0|0|x|x|x|x|
}; 

 sizeof(C) = 24; //

  • char是1,然后在int之前,地址偏移量得是4的倍数,所以char后面补三个字节,也就是char占了4个字 节,然后int四个字节,最后是short,只占两个字节,但是总的偏移量得是double的倍数,也就是8的倍 数,所以short后面补六个字节

 联合体union内存对齐的2大规则:

1.找到占用字节最多的成员;

2.union的字节数必须是占用字节最多的成员的字节的倍数,而且需要能够容纳其他的成员

//x64
typedef union {
    long i;
    int k[5];
    char c;
}D
  •  要计算union的大小,首先要找到占用字节最多的成员,本例中是long,占用8个字节,int k[5]中都是int类型, 仍然是占用4个字节的,然后union的字节数必须是占用字节最多的成员的字节的倍数,而且需要能够容纳 其他的成员,为了要容纳k(20个字节),就必须要保证是8的倍数的同时还要大于20个字节,所以是24个字 节。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值