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.youkuaiyun.com/pix_csdn/article/details/89210470