c/c++内存对齐实例说明

关于内存对齐,按8(4,2,1)字节对齐,指该变量的地址是8(4,2,1)的倍数。
以下为64位系统,g++ 5.4.0
先让我们看四个重要的基本概念:
1.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1,对于short型为2,对于int,float为4,long,long long,double,指针类型为8,单位字节。
64位系统:
sizeof(char):1
sizeof(short):2
sizeof(int):4
sizeof(long):8
sizeof(long long):8
sizeof(unsigned int):4
sizeof(float):4
sizeof(double):8
sizeof(pointer):8
2.结构体或者类的自身对齐值:
其成员中自身对齐值最大的那个值。(后面再与指定对齐值比较,取较小的作为实际对齐值。)

例(1)
指定按4字节对齐:
#pragma pack(4)
typedef struct _ST_1
{
char ch;
long l;
}ST_1;
#pragma pack()
结果:
sizeof _ST_1:12
st1’s addr:0x7fff80184d5c // Base
st1.l’s addr:0x7fff80184d60 // Base + 4
去掉#pragma pack(4),结果变为16。
#pragma pack(push) //保存以前的对齐状态,push是将以前的对齐状态压入栈
#pragma pack(1) //指定新的对齐状态,1个字节
//定义你的结构
//…………
#pragma pack(pop) //弹出栈,恢复以前的对齐状态
例(2)
#pragma pack(push)
#pragma pack(1)
struct A{
int a;
char b;
short c;
};
#pragma pack(pop);
sizeof(struct A) 结果为7。
改为#pragma pack(2) 后,A的大小为: 8
改为#pragma pack(4) 后,A的大小为: 8(a:base,b:base+4,c:base+6)此时b和c大小加起来小于4,放在一起。

4.数据成员、结构体和类的有效对齐值:
自身对齐值和指定对齐值中小的那个值。
64位系统下:默认按8字节对齐(gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1))
例(1)
typedef struct _ST_2
{
char ch;//1字节
short sh;//2字节,有效对齐值为2
long l;//8字节;有效对齐值为8
}ST_2;
结果:
sizeof _ST_2:16
st2’s addr:0x7ffef909f740 //Base
st2.sh’s addr:0x7ffef909f742 //Base + 2
st2.l’s addr:0x7ffef909f748 //Base +8
加上#pragma pack(4) 后,结果为12。
例(2)
typedef struct _ST_1
{
char ch;
long l;//有效对齐值为8
}ST_1;
结果:
sizeof _ST_1:16
st1’s addr:0x7ffc7daa4ae0 //Base
st1.l’s addr:0x7ffc7daa4ae8 //Base + 8

例(3)
ST_5含4个int型,大小为16字节。ST_6含2个int和1个long,大小也是16字节。他们与一个char型构成一个结构体时,对齐方式不同。
typedef struct _ST_5
{
int i1;
int i2;
int i3;
int i4;
}ST_5;//自身对齐值为4 放在其他结构体中时有效对齐值为4
typedef struct _ST_6
{
int i;
int i2;
long l;
}ST_6;//自身对齐值为8 放在其他结构体中时有效对齐值为8
typedef struct _ST_7
{
char ch;//1字节
ST_5 st5;//16字节
}ST_7;
typedef struct _ST_8
{
char ch;//1字节
ST_6 st6;//16字节
}ST_8;

sizeof _ST_7:20
st7’s addr:0x7fff1a5e2190 // Base
st7.st5’s addr:0x7fff1a5e2194 // Base+4 实际按4字节对齐
对比
sizeof _ST_8:24
st8’s addr:0x7fff1a5e21b0 // Base
st8.st6’s addr:0x7fff1a5e21b8 //Base+8 实际按8字节对齐

例(4)
字符数组有效对齐值是1.
typedef struct _ST_9
{
char ch;//1字节
char data[2];//1字节
}ST_9;
typedef struct _ST_10
{
char ch;//1字节
char data[60];//60字节
}ST_10;
结果:
sizeof _ST_9:3
st9’s addr:0x7ffd9fda8d5d //Base
st9.data 's addr :0x7ffd9fda8d5e //Base+1
sizeof _ST_10:61
st10’s addr:0x7ffd9fda8d60 //Base
st10.data 's addr :0x7ffd9fda8d61 //Base+1

例(11)
64位系统,string的自身对齐值:8
sizeof(string)结果是32。
string a; sizeof(a)结果是32。
string b; b初始话50个字符,sizeof(b)结果是32。
typedef struct _ST_11
{
char ch;//1字节
string str;
}ST_11;
结果:
sizeof _ST_11:40
st11’s addr:0x7ffecb064ff0
st11.str’s addr:0x7ffecb064ff8
查看string的size:
string str_test;
cout << “sizeof str_test is :” << sizeof(str_test) << endl;
结果:
sizeof str_test is :32

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值