没有合适的资源?快使用搜索试试~ 我知道了~
首页深入理解C++ sizeof:内存对齐与结构体实例
深入理解C++ sizeof:内存对齐与结构体实例
1 下载量 148 浏览量
更新于2024-09-01
收藏 85KB PDF 举报
本文详细解析了C++中的sizeof运算符在处理不同类型数据和结构体时的应用。sizeof是C++中用于获取数据类型或变量占用内存字节数的内置函数,它对于理解程序的内存管理和性能优化至关重要。 首先,sizeof在处理基本数据类型时返回的是确定的值,但当应用于结构体、联合体或类时,情况就复杂起来。例如,当我们试图用sizeof(S1)来计算一个包含char和int的结构体S1的大小时,结果可能会超过两个基本类型大小之和,这是因为编译器会根据内存对齐原则进行处理。对齐的目的是为了提高访问速度,通常要求结构体的首地址能被最宽基本成员类型整除,成员偏移量为成员大小的整数倍,且可能在成员之间插入填充字节以满足对齐要求。 对于嵌套结构体S2,计算其大小时,需要考虑嵌套结构体S1的最宽类型,即int。在这个例子中,S2的总大小会额外增加填充字节,使得S2的总大小为16字节。而获取结构体成员的偏移量,可以使用offsetof宏,如offsetof(S1, i)返回4,表示i成员在S1中的位置。 值得注意的是,程序员可以通过#pragma pack(n)来改变结构体的默认对齐方式,其中n指定字节对齐数,常见的取值有1、2、4、8和16。这允许在性能和内存使用之间进行权衡,但必须清楚地知道不同的对齐策略可能会影响其他编程语言或库的兼容性。 理解和掌握C++中的sizeof运算符以及内存对齐规则,不仅有助于编写高效、可移植的代码,还能提升程序员对内存管理的理解。通过实例和深入解释,本文为C++初学者和进阶者提供了一套全面的学习指南。
资源详情
资源推荐
详解详解C++ sizeof(下)(下)
主要介绍了C++ sizeof的相关资料,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
sizeof作用于基本数据类型,在特定的平台和特定的编译器中,结果是确定的,如果使用sizeof计算构造类型:结构体、联合
体和类的大小时,情况稍微复杂一些。
1.sizeof计算结构体计算结构体
考察如下代码:
struct S1
{
char c;
int i;
};
cout<<”sizeof(S1)=”<<sizeof(S1)<<endl;
sizeof(S1)结果是8,并不是想象中的sizeof(char)+sizeof(int)=5。这是因为结构体或类成员变量具有不同类型时,需进行成员
变量的对齐。《计算机组成原理》一书中说明,对齐的目的是减少访存指令周期,提高CPU存储速度。
1.1内存对齐原则内存对齐原则
(1)结构体变量的首地址能够被其最宽基本成员类型大小所整除;
(2)结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
(3)结构体的总大小为结构体最宽基本成员类型大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
有了以上三个内存对齐的原则,就可以轻松应对嵌套结构体类型的内存对齐。如下:
struct S2
{
char c1;
S1 s;
char c2;
};
在寻找S2的最宽基本数据类型时,包括其嵌套的结构体中的成员,从S1中寻找出最宽结构体数据类型是int,因此S2的最宽数
据类型是int。S1 s在结构体S2中的对齐也遵守前三个准则,因此
sizeof(S2)=sizeof(char)+pad(3)+sizeof(S1)+1+pad(3)=1+3+8+1+3=16字节,其中pad(3)表示填充3个字节。
结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获得,这个宏也在stddef.h中定义,如下:
#define offsetof(s,m) (size_t)&(((s *)0)->m)
例如获得S1中的偏移量,方法为
size_t pos = offsetof(S1, i); //pos等于4
1.2修改对齐方式修改对齐方式
1.2.1#pragma pack
#pragma pack(n)中n为字节对齐数,其取值为1、2、4、8、16,默认是8。结构体对齐时,
(1)成员的偏移量为成员本身大小和n二者最小值的整数倍;
(2)结构体最终大小是结构体中最宽基本类型成员大小和n二者中的最小值的整数倍。
考察如下代码:
#pragma pack(push) //将当前pack设置压栈保存
#pragma pack(2) //必须在结构体定义之前使用
struct S1
{
char c;
int i;
};
struct S2
{
char c1;
S1 s;
char c2
};
#pragma pack(pop) // 恢复先前的pack设置
下载后可阅读完整内容,剩余3页未读,立即下载
weixin_38682953
- 粉丝: 7
- 资源: 986
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- C++多态实现机制详解:虚函数与早期绑定
- Java多线程与异常处理详解
- 校园导游系统:无向图实现最短路径探索
- SQL2005彻底删除指南:避免重装失败
- GTD时间管理法:提升效率与组织生活的关键
- Python进制转换全攻略:从10进制到16进制
- 商丘物流业区位优势探究:发展战略与机遇
- C语言实训:简单计算器程序设计
- Oracle SQL命令大全:用户管理、权限操作与查询
- Struts2配置详解与示例
- C#编程规范与最佳实践
- C语言面试常见问题解析
- 超声波测距技术详解:电路与程序设计
- 反激开关电源设计:UC3844与TL431优化稳压
- Cisco路由器配置全攻略
- SQLServer 2005 CTE递归教程:创建员工层级结构
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功