首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

内存对齐(C+)

内存对齐的概念

引入代码

众所周知,C++的空类占用1个字节的内存空间,非空类占用的空间与类内的成员有关。但类中成员所占内存并不是连续的,拿以下代码举例:

#include

using namespace std;

class test1

{

char c1;

int a;

char c2;

}t1;

class test2

{

char c1;

char c2;

int a;

}t2;

class test3

{

int a;

char c1;

char c2;

}t3;

int main()

{

cout

cout

cout

system("pause");

}

在32位系统中,int类型占用4字节,char类型占用1字节,并且3个test类成员除顺序外完全一样,理论上输出结果均为。但实际t1,t2,t3的输出为,不仅大小与理论不符,t1所占空间还要大于后两者。这是因为成员变量的存储并不是连续的,而是根据一定的块大小存储(一般默认为4),这就是所谓的内存对齐

内存对齐的规则

对齐系数与有效对齐值

首先明确两个概念

对齐系数:每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。linux中默认为4,vs中默认为8,可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这一系数。

有效对齐值:是给定值#pragma pack(n)和类中最长数据类型长度中较小的那个,也叫对齐单位。比如vs中默认对齐系数为8,但该类中最长数据类型int为4,则有效对齐值为4。

为方便理解引入以下代码:

#include

using namespace std;

class test1

{

char c1;

char c3;

char c2;

}t1;

int main()

{

cout

system("pause");

}

虽然默认对齐系数为4,但该类中最长数据类型char为1,所以有效对齐值为1,结果输出为

内存对齐的具体规则为

第一个成员变量放在offset为0的地方,以后每个成员变量的对齐按照有效对齐值进行。

在成员变量完成各自对齐之后,类(结构或联合)本身也要进行对齐,对齐将按照有效对齐值进行。

类的总大小为最大对其数(每一个成员变量都有一个对其数)的整数倍。

如果存在类嵌套,则将嵌套类展开后对每一个成员变量对齐。

值得注意的是,n的缺省数值是按照编译器自身设置,gcc默认为4,合法的数值分别是1、2、4、8、16。(即编译器只会按照1、2、4、8、16的方式分割内存,其他值无效)

图示

test的内存分配如下

如果把使用#pragma pack(n)把默认的对齐系数改为1,代码如下

#include

using namespace std;

#pragma pack(1)//设定为 1 字节对齐

class test1

{

char c1;

int a;

char c2;

}t1;

class test2

{

char c1;

char c2;

int a;

}t2;

class test3

{

int a;

char c1;

char c2;

}t3;

int main()

{

cout

cout

cout

system("pause");

}

则此时t1,t2,t3输出结果均为6

摘自https://cloud.tencent.com/developer/article/2141807?areaSource=103001.1&traceId=ndSUzxOIIIjDMnnU1eNjv

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230405A06MTT00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券