C++内存对齐的实现 |
||||||||||||||||||||||
+ 目录内存对齐的基本原则:
空类/静态成员程序 1
?
对于一个什么都没有的空类,实际并不是空的,因为有默认的函数,具体可以参考 (待填入网址),大小是 1,这是因为需要有一个地址,C++ 不允许两个不同的对象有相同的地址,所以 C++ 中空的类和结构体大小都是 1。 程序 2
?
这个类的大小仍然是1,成员函数、静态成员函数、静态成员变量都是不占用类的内存的,这是因为这些东西都是类的,而不是每个对象分别存储。static变量就是存储在全局静态区。 需要注意的是,子类继承空类后,子类如果有自己的数据成员,而空基类的1个字节并不会加到子类中去。 程序 3
?
sizeof(D)为4。 再来看另一种情况,一个类包含一个空类对象数据成员,则空类对象的大小仍为1。 程序 4
?
在大多数编译器中,你会发现 sizeof(HaveAnInt) 输出为8。这是由于,Empty类的大小虽然为1,然而为了内存对齐,编译器会为HaveAnInt额外加上一些字节,使得HaveAnInt被放大到足够又可以存放一个int。
内置类型数据成员程序 1
?
程序 2
?
显然程序 1 输出的结果为 8,程序 2 输出的结果为 16 . 程序 1 最大的数据成员是4bytes,1+4=5,补齐为4的倍数,也就是8。而程序 2 为8bytes,1+8=9,补齐为8的倍数,也就是16。 程序 3
?
程序 4
?
程序 3 运行结果为 12,程序 4 运行结果为 8 class中的数据成员放入内存的时候,内存拿出一个内存块来,数据成员们排队一个一个往里放,遇到太大的成员时,不是将其劈成两半能放多少就放多少,而是等下一个内存块过来。这样的话,就可以理解为什么程序 3 和程序 4 两段代码输出结果不一样了,因为程序 3 是
结构体数据成员在默认条件下,内存对齐是以class中最大的那个基本类型为基准的,如果class中的数据成员包含其他class,则递归的取其中最大的基本类型来参与比较。 程序 1
?
程序 2
?
程序 1 和程序 2 运行结果均为:33 48 程序 1 和程序 2 中内存对其的基准均为8字节,BigData的大小均为33。在程序 1 中,BigData接下来是个int(4bytes),能够放下,这时候内存块还剩3bytes,而接下来是个double(8bytes),放不下,所以要等下一个内存快到来。因此,程序 1 的Data的size = 33 + 4 + (3) + 8 = 48,同理程序 2 应该是 程序 3
?
以上代码输出的结果为: 48 56
虚函数C++ 的类中如果有虚函数,类内就会有一个虚函数表的指针 _vptr,指向自己的虚函数表,vptr 一般都是在类的最前边(取决于编译器的实现)。
|