前言
创建一个类,不同的类内成员排序导致对象的sizeof大小不一致
环境:
hostnamectl
Static hostname: user-PC
Icon name: computer-vm
Chassis: vm
Machine ID:
Boot ID:
Virtualization:
Operating System: Deepin 23 Nightly
Kernel: Linux 5.10.60-amd64-desktop
Architecture: x86-64
g++
g++ (Debian 10.2.1-6) 10.2.1 20210110
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
示例
在没有继承的情况下:
class TTT
{
// 1.
int a ; // 2.
int c; // 3.
int *p; // 4.
double b; // 5.
int d; // 6.
};
int main(int argc, char * argv[])
{
cout << sizeof(TTT) << endl;
}
1. 即空类 sizeof(TTT)== 1
为了区分不同的对象,空类的大小为1
2.3. sizeof(TTT) == 8
4. sizeof == 8
即,一个地址大小8个字节
5. sizeof == 8
2.5. sizeof == 16
2.3.4. sizeof == 16
2.5.6. sizeof == 24
在有继承的情况下
class Base
{
virtual void fun(){ return; }
virtual void fun1(){ return; }
void func() { return ; }
};
class Child: public Base
{
};
sizeof(Base) == 8 函数定义不占用空间,虚表指针大小为一个地址
sizeof(Child) == 8
在该环境下,虚表指针的大小为8
解释
这是因为内存对齐的原因。
CPU读取内存不是一次读取单个字节,而是一块一块的来读取内存,块的大小可以是2,4,8,16个字节,具体取多少个字节取决于硬件。
假设CPU把内存划分为4字节大小的块,要读取一个4字节大小的int型数据,来看一下下面两种情况下CPU的工作量:
一、 寻址一次即可找到int
二、 寻址两次+一侧合并得到数据
为什么会有内存对齐?
主要是两个原因
平台原因:不是所有的硬件平台都能访问任意内存地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。为了同一个程序可以在多平台运行,需要内存对齐。
硬件原因:经过内存对齐后,CPU访问内存的速度大大提升。