C++内存对齐
为什么要内存对齐
方便计算机读写数据。对齐的地址一般都是 n(n = 2、4、8)的倍数。
1 个字节的变量,例如 char 类型的变量,放在任意地址的位置上;
2 个字节的变量,例如 short 类型的变量,放在 2 的整数倍的地址上;
4 个字节的变量,例如 float、int 类型的变量,放在 4 的整数倍地址上;
8 个字节的变量,例如 long long、double 类型的变量,放在 8 的整数倍地址上;
基本类型所占字节数
char 1
short 2
int 4
long 4(32位)或者8(64位)
long long 8
float 4
double 8
指针 4(32位)或者8(64位)
枚举 4
影响内存对齐的因素
变量的排列顺序
取消变量对齐:attribute((packed))
#pragma pack (n):让变量强制按照 n 的倍数进行对齐
内存对齐原则
sizeof一个结struct、class的结果必然是其内部的“最宽基本类型成员”的整数倍。
struct A { int a; char b; }; //sizeof(A)的结果是4的倍数。
struct B { int a; char b; double c; }; //sizeof(B)的结果是8的倍数。
struct C { A a; char b; }; //sizeof(C)的结果是4的倍数。
struct D { B a; char b; }; //sizeof(D)的结果是8的倍数。
结构体或类的自身对齐值:其成员中自身对齐值最大的那个值。
class A {
public:
int m_a;//占0~3字节
char m_b;//占第4字节
char m_c;//占第5字节,第6~7字节空着
};
class B {
public:
char m_a;//占第0字节,1~3空着
int m_b;//占4~7字节
char m_c;//占第8字节,第9~11空着
};
class C {
public:
char m_a;//占第0字节
char m_b;//占第1字节,2~3空着
int m_c;//占4~7字节
};
int main()
{
printf("%d\n%d\n%d\n", sizeof(A), sizeof(B),sizeof(C));//8 12 8
system("pause");
return 0;
}
虚函数表也遵循字节对齐
虚函数表指针永远在类的开头位置,并且虚函数表指针占用4(32位)或8(64位)字节。
class D {
public:
virtual void f() {}
};
class E {
public:
virtual void f() {}
double m_a;
};
class F {
public:
virtual void f() {}
int m_a;
};
class G {
public:
virtual void f() {}
char m_a;
};
int main()
{
//结果4 16 8 8
printf("%d\n%d\n%d\n%d\n", sizeof(D), sizeof(E), sizeof(F), sizeof(G));
system("pause");
return 0;
}
参考文章
https://blog.csdn.net/weixin_48896613/article/details/127371045