1.基本变量类型所占内存大小
数据类型 | 32位LInux | 大部分64位LInux | 64位windows |
char | 1字节 | 1字节 | 1字节 |
short | 2字节 | 2字节 | 2字节 |
int | 4字节 | 4字节 | 4字节 |
float | 4字节 | 4字节 | 4字节 |
long | 4字节 | 8字节 | 4字节 |
double | 8字节 | 8字节 | 8字节 |
long long | 8字节 | 8字节 | 8字节 |
指针point | 4字节 | 8字节 | 8字节 |
枚举enum | 4字节 | 4字节 | 4字节 |
联合体union | 取联合体中最大变量类型大小 |
2.影响内存对齐情况,偏移量计算
#pragama pack(n)
让变量强制按照n的倍数进行对齐
offsetof(结构体类型,求偏移量的成员)
使用offsetof求偏移量,头文件为stddefe.h
3.对齐规则
struct S1
{
char c1;
int i;
char c2;
};
struct S2
{
char c1;
char c2;
int i;
};
int main()
{
struct S1 s;
struct S2 s2;
printf("%d/n",sizeof(s)); //12
printf("%d/n",sizeof(s2)); //8
}
由于对齐规则的存在结构体内成员位置不同会影响到内存大小
1.第一个成员与结构体变量偏移量为0的地址处
2.(从第二个成员开始)其他成员变量要对齐到对齐数的整数倍的地址处
对齐数=编译器默认的一个对齐数与该成员大小的较小值(vs默认为8,linux没有默认对齐数成员自身大小就是对齐数)
eg.1
struct S1
{
char c1;
int i;
char c2;
};
char c1从0偏移量开始占一字节,int占四字节第二个成员从对齐数(4<8)整数倍开始
内存存储情况 | 偏移量 |
c1(1字节) | 0 |
1 | |
2 | |
3 | |
i(4字节) 对齐数:4 | 4 |
5 | |
6 | |
7 | |
c2(1字节) 对齐数:1 | 8 |
9 | |
10 | |
11 |
因为结构体大小为成员中最大对齐数整数倍所以为4的整数倍因此内存大小为12而不是9
struct S2
{
char c1;
char c2;
int i;
};
内存存储情况 | 偏移量 |
c1(1字节) | 0 |
c2(1字节) 对齐数:1 | 1 |
2 | |
3 | |
i(四字节) 对齐数:4 | 4 |
5 | |
6 | |
7 |
最大对齐数4,内存所占8是4倍数因此结构体所占内存为8
3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍
4.如果嵌套了结构体,嵌套的结构体对齐到自己成员的最大对齐数的整数倍处,结构体整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍
struct S3
{
double d;
char c;
int i; //16
};
struct S4
{
char c1;
struct S3;
double d;//32
};
内存存储情况 | 偏移量 |
char c1 (1字节) | 0 |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
struct s3 (16字节)最大对齐数:8 | 8 |
......... | |
23 | |
double d(8字节)对齐数:8 | 24 |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 |
4.一些例题
struct S3
{
double d;
char c;
int i; //16
};
内存存储情况 | 偏移量 |
double d (8字节) | 0 |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
char c (1字节)对齐数:1 | 8 |
9 | |
10 | |
11 | |
int i(四字节)对齐数:4 | 12 |
13 | |
14 | |
15 |