C++字节对齐与位域
环境:
win7_x64旗舰版、VS2015企业版
一、字节对齐:
说明:为了提高 CPU 的存储速度,编译器会对 struct 和 union的存储进行优化,即进行字节对齐。
1. 指定对齐参数值:通过#pragma pack(push, n)设置。
2. 自身对齐参数值:每个内部类型自身也都有一个对齐参数,一般来说这个对齐参数就是 sizeof(type) 的值,也就是char的自身对齐参数是1,short是2,int是4,float也是4,double是8等。
3. 有效对齐参数值:内部类型的有效对齐是指它的自身对齐参数和指定对齐参数中较小的那个值;
4. 结构体整体的有效对齐参数值:是指它的成员中,有效对齐参数最大的那个值。
例如:
///< 假设按4字节对齐
#pragma pack(push, 4)
struct data {
char a; //a的有效对齐参数值是min(1,4)为1字节,从第1字节开始,占1字节
char b; //b的有效对齐参数值是min(1,4)为1字节,从第2字节开始,占1字节
long long c; //d的有效对齐参数值是min(8,4)为4字节,从第5个字节开始,占8字节
short d; //e的有效对齐参数值是min(2,4)为2字节,从第13个字节开始,占2字节
};
它们的和为1字节(a)+1字节(b)+2字节(填充)+8字节(c)+2字节(d)=14字节。
因为整体结构体还需要进行对齐,结构成员最大有效对齐参数值为4,所以整个结构为4的整数倍,最后的总大小为4 * 4 = 16字节。
二、位域:
说明:C/C++中以一定区域内的位(bit)为单位来表示的数据成为位域,位域必须指明具体的数目,位域的作用主要是节省内存资源,使数据结构更紧凑。
1. 取地址操作符&不能应用在位域字段上;
2. 位域字段不能是类的静态成员;
3. 位域字段在内存中的位置是按照从低位向高位的顺序放置的;
4. 位域的对齐
a. 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
b. 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
c.如果相邻的两个位域字段的类型不同,则各个编译器的具体实现有差异,VC6采取不压缩方式,采用第一节说的字节对齐方式进行。
d. 整个结构体的总大小采用字节对齐方式的第4点。
e. 如果位域字段之间穿插着非位域字段,则不进行压缩,采用第一节说的字节对齐方式进行。
f. 无名的位域不能使用,只能用于填充,位宽为0表示强制下一位域对齐到当前类型的边界。
例如:
///< 假设按4字节对齐
#pragma pack(push, 4)
struct data {
short a : ; //从第1个字节开始,占1字节,使用7位
short b : ; //从第2个字节开始,占1字节,使用5位
long long e : ; //与上个类型不一致,e的有效对齐参数值是min(8,4)为4字节,所以从第5个字节开始,占8字节,使用4位
char f : ; //与上个类型不一致,f的有效对齐参数值是min(1,4)为1字节,所以从第13个字节开始,占1字节,使用1位
};
它们的和为1字节(a)+1字节(b)+2字节(填充)+8字节(e)+1字节(f)=13字节。
因为整体结构体还需要进行对齐,结构成员最大有效对齐参数值为4,所以整个结构为4的整数倍,最后的总大小为4 * 4 = 16字节。
///< 假设按4字节对齐
#pragma pack(push, 4)
struct bits8 {
short a : ; //从第1个字节开始,占1字节,使用3位
short : ; //占位,占21位,强制下一类型对齐到边界
char : ; //占位,从第3个字节开始,占3位
char b : ; //从第3字节第4位开始,使用5位
int i : ; //从第5个字节开始,占4字节,使用4位
};
它们的和为2字节(a)+1字节(b)+1字节(填充)+4字节(i)=8字节。
因为整体结构体还需要进行对齐,结构成员最大有效对齐参数值为4,所以整个结构为4的整数倍,满足条件,最后的总大小为8字节。
参考:
https://www.cnblogs.com/pure/archive/2013/04/22/3034818.html
https://jocent.me/2017/07/24/bit-field-detail.html
C++字节对齐与位域的更多相关文章
- C语言基础--结构体对齐,位域,联合体
结构体对齐 1--结构体对齐的原因与意义 许多计算机系统对基本数据类型的可允许地址做出了一些限制,要求某种类型的对象的地址必须是某个值K(通常是2,4,8)的倍数,而这个k则被称为该数据类型的对齐模数 ...
- sizeof(结构体)和内存对齐以及位域
Win32平台下的微软C编译器的对齐策略: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除: 备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该 ...
- c/c++ 字节对齐
c 字节对齐 概念: 结构体里会包括各种类型的成员,比如int char long等等,它们要占用的空间不同,系统为一个结构体开辟内存空间时,会有2种选择. 第一种:节省空间的方案,以上面的列子来说的 ...
- C语言字节对齐问题详解
引言 考虑下面的结构体定义: typedef struct{ char c1; short s; char c2; int i; }T_FOO; 假设这个结构体的成员在内存中是紧凑排列的,且c1的起始 ...
- C/C++结构体字节对齐详解
结构体的sizeof先看一个结构体:struct S1{ char c; int i;}; sizeof(S1)在VC6中按默认设置得到的结果为8.我们先看看sizeof的定义——size ...
- C语言字节对齐问题详解(对齐、字节序、网络序等)
首先说明一下,本文是转载自: http://www.cnblogs.com/clover-toeic/p/3853132.html 博客园用的少,不知道怎么发布转载文章,只能暂时这样了. 引言 考虑下 ...
- C++进阶3.字节对齐 联合
C++进阶3.字节对齐 联合 20131011 多益和金山笔试 知识漏洞 20131011 前言: 今天下午是多益网络的笔试,整体感觉还好,但是找到很多的知识漏洞.一直笔试到6:00,然后紧张的从会生 ...
- <摘录>字节对齐(强制对齐以及自然对齐)
struct {}node; 32为的x86,window下VC下sizeof(node)的值为1,而linux的gcc下值为0: 一.WINDOWS下(VC--其实GCC和其原理基本一样,象这种问题 ...
- C语言字节对齐问题详解【转】
引言 转自:http://www.cnblogs.com/clover-toeic/p/3853132.html 考虑下面的结构体定义: 1 typedef struct{ 2 char c1; 3 ...
随机推荐
- jq后加标签的事件(live事件)
在使用中 live可以对未来元素起作用(比如:js后加的div等) live在jq1.9以上版本已经废除 原:$('#del').live('click',function(){}) 改:$(' ...
- SecureCRT通过SSH2协议远程登录Ubuntu 18.04的过程总结
reference: https://blog.csdn.net/ghostar03/article/details/47441715 https://blog.csdn.net/u011186256 ...
- Excel汉字转换拼音首字母缩写的函数
打开Excel->工具->宏->Viaual Basic编辑器在弹出来的窗口中对着VBAproject点右键->插入->模块下面会出现一个名为"模块1" ...
- Devexpress GridControl 多选
以前dev的多选要自己处理,一般的处理方式就是在单元格中添加checkbox控件.后来的版本中dev增加了多选的支持,只需要设置一下属性就可以了,属性如下图: 然后效果设计页面就是这个样子: 运行以后 ...
- web前端的前景
随着时代的发展,现在从事IT方向的人有很多,所以励志要成为前端开发工程师的人有很多.当然也有很多人在犹豫不知道该从事哪个方向,我今天就是来给大家分析一下Web前端开发的前景.包括工作内容,发展前景和薪 ...
- DevExpress v18.2新版亮点——DevExtreme篇(三)
行业领先的.NET界面控件2018年第二次重大更新——DevExpress v18.2日前正式发布,本站将以连载的形式为大家介绍新版本新功能.本文将介绍了DevExtreme Complete Sub ...
- Python全栈day9习题
本内容主要为If条件语句和while循环的相关知识. 一.使用while循环输入1 2 3 4 5 6 8 9 10 i = 1 while i < 11: if i == 7: pass el ...
- 20165214 2018-2019-2 《网络对抗技术》Exp5 MSF基础应用 Week8
<网络对抗技术>Exp5 MSF基础应用 Week8 一.实验目标与内容 1.实践内容(3.5分) 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体我 ...
- Javascript学习---倒计时
function fn() { var now = new Date(); // 此时此刻的时间 var old = new Date(2018, 9, 30); // 2018,6,25 var t ...
- contos7 go 环境搭建
安装包下载地址为:https://golang.org/dl/.(网址打不开请FQ) 根据不同系统,选择对应的安装包: 解压安装 1.下载源码包:go1.10 linux/amd64 2.将下载的源码 ...