目录
- 一个类占有的内存
- 结构体的大小
- sizeof
study and think. then you will get more.
一个类占有的内存
一个class类对象需要占有的内存空间如何计算:
- 非静态成员变量的综合。
- 编译器为了CPU计算,作出的数据对齐处理。
-
虚函数,产生的额外负担。
- 空类Car的size:1个字节。编译器在执行这个类的时候,作出一个class car的object。并且这个object的地址还是独一无二的,于是编译器就会给空类创建一个隐含的一个字节的空间。
- 只有成员变量的Size:如果有两个int类型的成员变量,那就是8个字节。
- 包含静态成员变量的Size,只算非静态成员的内存大小。
- 在两个int类型成员前面添加一个char类型成员大小为12,这是因为字节对齐的原因。
- 成员函数不占用类空间
- 带有虚函数的类,会增加一个虚表指针(virtual table:vptr)的大小,指针的大小一般是一个int的大小。
结构的内存大小
系统在存储结构体变量时存在一个“边界对齐”的问题。这是编译器对变量存储的一个特殊处理,为了提高CPU的存储速度,编译器对一些变量的地址做了对齐处理。在默认情况下,编译器规定各个成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量所占用的字节数的倍数。编译器会按照成员列表的顺序一个接接一个给给每一个成员分配内存的,字节对齐遵循以下两个原则:
- 结构体的每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如果需要编译器会在成员之间加上填充字节。
- 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如果需要编译器会在最末一个成员之后加上填充字节。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//结构体1
struct Mystruct1
{
double data_db;
char data_ch;
int data_i;
};
//结构体2
struct Mystruct2
{
char data_ch;
double data_db;
int data_i;
};
对于第一个结构体,double8个字节,其前面是0,是整数倍;第二个成员是char,一个字节,其前面是8,8/1也是整数倍;对于第三个成员int,前面是9,不是整数倍,所以char扩充为4;最后是16,是最大8的整数倍。 第二个结构体,(1 + 7) + 8 + (4 + 4)。分析按照上面的方式。
sizeof
- sizeof计算对象的大小也是转换成对象类型来计算的,对于同类型的不同对象使用sizeof操作,得到的值是一样的。
- sizeof可以对函数调用求值,就相当于对该函数的返回值类型求sizeof。
- sizeof的计算发生在编译时刻,所以它可以被当作常量表达式来使用。
- 基本数据类型的sizeof
- char —-1
- short —-2
- int —-4
- long —-4
- float —-4
- double —-8
- longdouble —-8
- 指针类型的数据对象,无论其指向谁,其大小都是4个字节
- 数组类型的对象所占有的大小:数组的sizeof值等于数组所占用的内存字节数。在作为参数传递的时候,数组名变蜕化成一个相应类型的指针了,所以大小是一个指针的大小,即4。
- 结构的内存大小见上面