字节 |
short |
int |
float |
long |
*(地址) |
double |
long long |
32位 |
2 |
4 |
4 |
4 |
4 |
8 |
8 |
64位 |
2 |
4 |
4 |
8 |
8 |
8 |
8 |
*有无unsigned修饰都一样
- 编译器pack指令 #pragma pack(n)——定义n字节对齐
- C++固有类型的对齐取编译器对齐与自身大小中较小的一个
- 32位C++默认8字节对齐。gcc编译器默认4字节对齐
- static变量在静态区,sizeof均不纳入计算
- 在编译阶段处理,sizeof作用范围内的内容不能被编译,所以sizeof()内的运算不被执行
- sizeof(函数)=sizeof(返回值类型)
- sizeof和strlen:sizeof计算字符串容量,算’\0’,strlen计算字符串长度,到’\0’截止
- 类:非static数据成员变量+虚函数指针+对齐;无论多少个虚函数,都只有一个指向虚函数表的指针(4字节)
- 联合体:最长成员的大小对齐
- 带位域:相邻位域字段的两个变量若类型相同,当两个字段位宽和小于此类型大小时,二者紧邻存储;若二者位宽和大于本类型大小,则第二个字段从新存储单元开始,偏移量为其类型大小整数倍。若相邻位域字段类型不同,则视编译器决定是否压缩存储,VC6不压缩,Dec-C++压缩。如果位域字段间穿插着非位域字段,不压缩。
- 数组:数组占内存字节=元素个数*元素长度; 当数组作为函数参数传递时,蜕变成指针
double* (*a)[3][6];
cout<<sizeof(a)<<endl; // 4
cout<<sizeof(*a)<<endl; // 72
cout<<sizeof(**a)<<endl; // 24
cout<<sizeof(***a)<<endl; // 4
cout<<sizeof(****a)<<endl; // 8
- a是一个很奇怪的定义,他表示一个指向 double*[3][6]类型数组的指针。既然是指针,所以sizeof(a)就是4。
- *a就表示一个元素为double*、大小为[3][6]的多维数组类型,因此sizeof(*a)=3*6*sizeof(double*)=72。
- **a表示一个double*[6]类型的数组,所以sizeof(**a)=6*sizeof(double*)=24。
- ***a就表示其中的一个元素,也就是double*了,所以sizeof(***a)=4。
- ****a,就是一个double了,所以sizeof(****a)=sizeof(double)=8。
5、结构体(编译器考虑默认8字节对齐的情况下):
- 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;(这条在结构体作为结构体成员时考察)
- 结构体每个成员相对于结构体首地址的偏移量(offset)都是此成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
- 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
由于结构体的成员可以是复合类型,比如另外一个结构体,所以在寻找最宽基本类型成员时,应当包括复合类型成员的子成员,而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。
举例理解:
找S3中最长成员时,将S1打散,找S1、S3中所有基础变量最长的,以其长度为S3对齐字节数:int 4
确定S3对齐字节数后,挨个放置S3成员变量时,将S1看作一个整体(8字节复合变量)一次性存放,并且S1的对齐方式为其自身对齐字节数(4字节对齐。S1也是结构体,有自己的对齐字节数,计算偏移量时按照自己的对齐字节数计算)
实验验证正确:
sizeof(s)=32。
取结构体S5变量地址,看各个成员在内存中的存放情况:
- 左边是地址,右边是十六进制表示的成员ASCII值,cc是补齐字节
- 值0x61:’a’,占一个字节
- 0x62、0x01-0x00:’b’、1,共占8个字节(s1当作一个整体,自身对齐字节数4,即开始存放的地址对结构体首地址偏移量为4的倍数,故补齐3个字节)
- 0x31-0x00:”12345”,共占6字节,含’\0’,(s2对结构体首地址偏移量1字节倍数,即紧邻s1)
- 0x00-0x40:2.0,共占8字节(因为前面加起来刚好18字节,double为8字节对齐,对结构体首地址的偏移为8的倍数,故补齐了6个字节)
举一反三:
sizeof(s)=32;
- c1占1字节——1
- s1对齐4,占8字节——1+3+8=12
- s2对齐8,占16字节——12+4+16=32
当然了:
如果S5再加个短于double的变量中double后面,如char或int,则会因为结构体大小要为最长成员整数倍而补齐成40字节(已经实验验证)
最后:
sizeof(结构体) 还和编译器有关,取二者较小者
版权声明:本文为EVEcho原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。