结构体联合体sizeof内存求值 - 对齐数

讲解下struct和union的内存求值和对齐
以题目讲解

不同位数下类型字节大小

一定要搞清楚编辑器,一般编辑器中的类型字节如图:

类型16位平台32位平台64位平台
char1个字节1个字节1个字节
short2个字节2个字节2个字节
int2个字节4个字节4个字节
unsigned int2个字节4个字节4个字节
float4个字节4个字节4个字节
double8个字节8个字节8个字节
long4个字节4个字节8个字节
long long8个字节8个字节8个字节
unsigned long4个字节4个字节8个字节
指针2个字节4个字节8个字节

一般我使用的是64位的编译器,下面来看看对齐规则

 

内存对齐规则

规则

  • 结构体的第一个成员直接对齐到相对于结构体变量起始位置为0处偏移。
  • 从第二个成员开始,要对齐到某个【对齐数】的整数倍的偏移处。
  • 结构体的总大小,必须是最大对齐数的整数倍。每个结构体成员都有一个对齐数,其中最大的对齐数就是最大对齐数
  • 如果嵌套了结构体的情况。嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

 

struct 内存对齐求值

  • 举例:struct内存求值
#include <stdio.h>
#pragma pack(16)
struct BBB {
    long num;
    char ha;
    short ba[5];
}b;

int main() {
    printf("%d\n", sizeof(b.num));//8
    printf("%d\n", sizeof(b.ha)); //1
    printf("%d\n", sizeof(b.ba)); //10 ,short大小是2
    //最大对齐数是8

    printf("%d\n", sizeof(BBB));
    return 0;
}

//这里ba数组的最大对齐数是2,因为short大小2小于定义的对齐数16

//sizeof(BBB)=8+1+1+(2*5)=20,这里的1是为了让ba数组对齐到2的倍数
//但是对齐规则里面有个结构体的总大小,必须是最大对齐数的整数倍
//这里最大对齐数是8,也就是结果需要是8的倍数,最终等于sizeof(BBB)=24

在这里插入图片描述

 

嵌套struct内存对齐求值

  • 如果有嵌套结构体呢 :
#include <stdio.h>
#pragma pack(16)
struct BBB {
    long num;
    char ha;
    short ba[5];
    struct BBB2
    {
        int s; //4
        int ba2[5]; //20 
        char ha2[2]; //2
    }b2;  //4+20+2=26。对齐=4的倍数=28 
}b;

int main() {
    printf("%d\n", sizeof(b.num));//8
    printf("%d\n", sizeof(b.ha)); //1
    printf("%d\n", sizeof(b.ba)); //10 ,short大小是2
    printf("%d\n",sizeof(b.b2));//28,见上面
    //最大对齐数是8

    printf("%d\n", sizeof(BBB));
    return 0;
}
//sizeof(BBB)=8+1+1+(2*5)=20,后面嵌套的BBB2最大对齐数是4,对齐大小是28,所以从4的倍数出发,这里是20开始,正好,sizeof(BBB)=20+28=48,正好是8的倍数

 

union的内存大小求值

解释下union的内存大小求值

union大小计算准则

1、至少要容纳最大的成员变量
2、必须是所有成员变量类型大小的整数倍 —— 记住是成员变量类型 char c[7]算 1

  • 举例:求sizeof(union)
#include<stdio.h>
 
//联合体
union u2  
{
    char a;  //1
    int b; //4
    short c; //2
    double d; //8
    int e[5]; //20
}U3;
 
//主函数
int main(){ 
    printf("%d\n",sizeof(U3));//输出24
    return 0;
}

 

struct嵌套union内存对齐求值

#include <stdio.h>
#pragma pack(16)
struct BBB {
    int num;//4
    char ch; //1
    char pa[3]; //3
    union {
        int a; //4
        float b; //4
    } myUnion;//这个union内存大小等于4
}b;

int main() {
    printf("%d\n", sizeof(b));
    //4+1+3+4=12 ; 到char pa[3]时候这时候正好到地址8,然后union的内存是4,对齐数,要求是它的整数倍所以正好从8开始,最终结果12。满足是对齐数4,1,4的倍数
    return 0;
}

 

其他内容见专栏的结构体和联合体的文章
如果有啥补充的后续更新

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值