结构体/类内存对齐的规则
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
备注:为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员之后加上填充字节(trailing padding)。
class A { int a; short b; int c; char d; }; class B { double a; short b; intc; char d; }; 在32位机器上用gcc编译以上代码,求sizeof(A),sizeof(B)分别是多少。 a、12 16 b、12 12 c、 16 24 d、16 20
A -----> △△△△||△△==||△△△△||△===
B -----> △△△△△△△△||△△==(short)△△△△(int)||△=======
根据规则三,sizeof(B) % 8 == 0 所以只能选C
sizeof(a1) = 8 根据前面规则, 答案是24
32位机器指针占用4个字节, 64位机器指针占用8个字节
这道题目改了内存对齐的模式数
sizeof(A)= 8 , sizeof(B) = 12
c++定义一个空的类CTest,CTest没有定义任何成员变量和成员函数,在32位机器上,以下结论正确的有:
C++标准规定类的大小不为0,空类的大小为1,当类不包含虚函数和非静态数据成员时,其对象大小也为1。
对有虚函数的类来说,必须为它的对象提供运行时类型信息(RTTI,Run-Time Type Information)和关于虚函数表的信息,常见的做法是在对象中放置一个指向虚函数表的指针,此外,为了支持RTTI,许多编译器都把该类型信息放在虚函数表中。但是,是否必须采用这种实现方法,C++标准没有规定,主流编译器均采用的一种方案。
虚函数、成员函数[包括静态与非静态]、和静态数据成员都是不占用对象的存储空间的
对象大小 = 虚函数指针 + 所有非静态数据成员大小 + 因对齐而多占的字节
第二个内存对齐4+4, 第三个只有一个成员函数,大小为1, 第四个虚函数指针,大小为4