【C/C++】内存对齐超详解

1.基本变量类型所占内存大小

数据类型32位LInux大部分64位LInux64位windows
char1字节1字节1字节
short2字节2字节2字节
int4字节4字节4字节
float4字节4字节4字节

long

4字节8字节4字节
double8字节8字节8字节
long long8字节8字节8字节
指针point4字节8字节8字节
枚举enum4字节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字节)           对齐数:44
5
6
7
c2(1字节)        对齐数:18
9
10
11

因为结构体大小为成员中最大对齐数整数倍所以为4的整数倍因此内存大小为12而不是9

struct S2
{
    char c1;
    char c2;
    int i;
};
内存存储情况偏移量
c1(1字节)       0
c2(1字节)        对齐数:11
2
3
i(四字节)      对齐数:44
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字节)对齐数:824
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字节)对齐数:18
9
10
11
int i(四字节)对齐数:412
13
14
15

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值