C++内存对齐规则
预备知识
C++基本数据类型的字节数
注意:Windows系统32位和64位,同一基本类型数据占用字节一致。Linux下涉及到long类型则有所区别。
接下来测试一下64位 long类型所占字节大小
Windows下
Linux下
1 默认对齐规则
- 默认按结构体中数据成员所占最大字节对齐。
- 按照声明顺序分配内存
- 数据成员变量的起始地址必须是该自身所占字节大小的整数倍。
- 结构体的大小必须是数据成员所占字节最大的整数倍,不够的补空白字节。
#include <iostream>
using namespace std;
struct A{
char c1;
char c2;
int val;
};
struct B{
char c1;
int val;
char c2;
};
int main(){
A a;
cout<<"A的结构体大小:"<<sizeof(a)<<endl; //测试结果:8
B b;
cout<<"B的结构体大小:"<<sizeof(b)<<endl; //测试结果:12
return 0;
}
分析一下结构体A结果:
S1:根据第一条规则,默认对齐方式是最大成员变量,所以按照4字节对齐。如上图每个格子代表一个字节,每四个一组。
S2:根据第二条规则,按照声明顺序分配内存,首先先考虑C1,在考虑C2,最后考虑val。
S3:根据第三条规则,(为方便讲述,默认位置为0,因为0一定是结构体得整数倍),C1占1个字节,放置第1个位置即可,
C2占1个字节,放第2个位置即可,(向这种占1个字节得可以放任意位置,因为每个地址都是1的整数倍),val占4个字节,不能放在2和3位置,因为2,3不是4的整数倍,所以空着,从下一行4开始放。
最后,从上图我们可以看出,结构体A占用8个字节。
结构体B的数据成员内存分配图如下。
分析过程同上:由上图可以,结构体B占用12个字节。
2 指定对齐规则
-
通过#pragma pack(num)指定结构体按照num字节对齐
其中num = 1,2,4,8,…, 2 n 2^n 2n
-
结构体按照数据成员所占最大字节和指定字节中最小的那个对齐。即min(指定的字节,默认的字节对齐)
-
按照声明顺序分配内存。
-
数据成员变量的起始地址必须是该min(指定的字节,自身所占字节大小)的整数倍。
-
结构体的大小必须是min(指定的字节,默认的字节对齐)的整数倍,不够的补空白字节。
#include <iostream>
using namespace std;
#pragma pack(2)
struct A{
char c1;
char c2;
int val;
};
struct B{
char c1;
int val;
char c2;
};
#pragma pop()
int main(){
A a;
cout<<"A的结构体大小:"<<sizeof(a)<<endl; //测试结果:6
B b;
cout<<"B的结构体大小:"<<sizeof(b)<<endl; //测试结果:8
return 0;
}
结构体A的成员放置位置图如下,分析过程同上
结构体A的成员放置位置图如下,分析过程同上