当 sizeof() 遇到 struct{} 和 class{}

sizeof基本的用法这里就不说的,无非是确定对象

  • 什么时候是指针;
  • 什么时候是数组;
  • 16位/32位/64位机器中int,long,指针的大小;

这一篇主要介绍sizeof(结构体)以及sizeof(类)的计算方法:

  • sizeof(结构体)
    • 麻烦的原因
      • 计算机系统的字节对齐(为了快速读写数据)
      • static静态变量
      • 不同位系统下int,long,指针的大小
    • 计算的准则
      • 结构体变量的首地址要能被其最宽的基本类型整除(主要用于结构体的嵌套)①
      • 结构体中数组,结构体的长度需要拆分成单基本类型的长度计算②
        • 例如char ch[10]在结构体里应该看作10个连续的char,而非一个长为10的数组
      • 字节对齐
        • 当结构体成员的首地址不能被当前数据类型长度整除时,应填充字节使其能被整③
        • 结构体总大小为最宽基本成员的整数倍④
      • static不占结构体空间,64位系统指针为8字节
    • 计算方法

1.先找出基本长度最大的变量

struct stu2{
    char ch2;
    float f1;
    float f2;
};
struct stu1{
    int a;
    char ch1;
    stu2 stu;
    long long b;
};


上面stu1中基本长度最大的是哪个呢?

是b,它是long long 型,长度为8;虽然stu2的整体长度为12(这里先不解释为什么是12),但是需要把它拆分成三个元素,char,float和float三者最长的为float(4),所以stu1最长的宽度为8;

2.按顺序放入变量,计算长度

不同的顺序可能导致struct大小不一。

先来算stu2的长度,假设结构体首地址是0x00,则ch2放在0x00处(任何一个最开始的变量都能放到0x00处),现在开始放f1.

f1的长度为4,根据③,f1首地址不能是0x01,f1首地址应是0x04。之后再放置f2,这样sizeof(stu2)的大小就是1+3(补)+4+4 = 12。

现在来看sizeof(stu1),同样先找最宽的元素,为long long型,宽度为8。

依次放入元素(假设首地址为0x00),a放在0x00-0x03处没问题,ch1放在0x04处也没问题。

现在需要放stu2中的变量,按照③ch2放在0x05处没有问题,但是别忘了还有①!!!所以ch2放在了0x08处(好好体会一下)

然后是f1,放在0x0C-0x0F处;f2放在0x10-0x13处。

最后是long long,根据③,b要从0x18处开始存放,到0x1F结束所以sizeof(stu1)长度为32

3.若b后还有一个char ch3呢?

此时ch3放在0x20处,但是不代表结构体内存到0x20处就截止。

根据④,需要在0x20后填充7个字节(8 - 1),最终长度为40。

所以元素位置对结构体大小还是有影响的。若ch3在ch1后面,则长度还是32。

至此就计算完了……

 

  • sizeof(类)
    • 类的基本计算方法与结构体类似
    • 类中的方法(函数)不占大小(包括构造函数和析构函数)
    • 类中若有虚函数,会有一个虚函数表,此表相当于一个指针(无论多少虚函数,只有一个表)

空的结构体和类大小都为1。

若类/结构体中存在空数组,则大小为0。

class T{
    char ch[0];
};

//sizeof(T)为0

如果想知道16/32/64位系统各个类型变量的大小,去看这一篇吧。

https://blog.csdn.net/pix_csdn/article/details/89210470

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值