内存对齐的基本原则:
- 结构(struct/class)的内置类型数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的起始位置要从自身大小的整数倍开始存储(特别注意64位机器的指针大小为8个字节)。
- 如果一个结构A里有结构体成员B,则结构体B要从其内部"最宽基本类型成员”的整数倍地址开始存储(如struct a里存有struct b,b里有char, int, double等元素,那b应该从8的整数倍位置开始存储)。
- 结构体的总大小为结构体的有效对齐值的整数倍,结构体的有效对齐值的确定:
- 当未明确指定时,以结构体或结构体所包含结构体成员中最长的成员长度为其有效值。
- 当用#pragma pack(n)指定时,以n和结构体中最长的成员的长度中较小者为其值。
- 当用__attribute__ ((packed))指定长度时,强制按照此值为结构体的有效对齐值。
- 不管# pragma pack和__attribute__如何指定,结构体内部成员的自对齐仍然按照其自身的对齐值。
- union以结构里面size最大元素为union的size,因为在某一时刻,union只有一个成员真正存储于该地址。
空类/静态成员
程序 1
class A{
};
int main() {
cout << sizeof(A) << endl; // 1
}
对于一个什么都没有的空类,实际并不是空的,因为有默认的函数,具体可以参考 (待填入网址),大小是 1,这是因为需要有一个地址,C++ 不允许两个不同的对象有相同的地址,所以 C++ 中空的类和结构体大小都是 1。
程序 2
class A{
A(){
}
~A(){
}
void print() {
printf("print()\n"); }
void foo() {
printf("print()\n"); }
static void sprint() {
printf("sprint()\n"); }
};
int main