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 ...
随机推荐
- java算法01 - 链表
1.链表 在Java中实现链表,每个节点都有一个值,然后把它链接到下一个节点.下面来看一下节点的实现 class Node<E> { private E e; private Node&l ...
- ImitateUCM项目启动Tomcat的过程
启动各种报错:什么source not found ....然而解决后发现都不是问题关键 下面我讲下我的理解(也许这也不是关键,但是通过该这些,我的问题解决了) (1)重新部署Tomcat时,要同步更 ...
- P2886 [USACO07NOV]牛继电器Cow Relays
题目描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...
- Mac下安装证书fiddlerRoot.cer
Step 1: 设置Mac的代理如下 Step 2:打开127.0.0.1:8888,下载fiddlerRoot.cer; Step 3:下载好了,双击安装,但是默认这个证书是不可信的,你需要在钥匙串 ...
- MySQL80修改密码
mysql> update user set password=password('123') where user='root' and host='localhost'; ERROR 106 ...
- 微信小程序实际开发中学习
三个概念 微信:就是一个聊天工具 微信公众号:企业或个人用于管理其粉丝/用户的应用(类似于APP) 微信小程序:不需要下载安装直接可以使用的软件/应用/APP 小程序与公众号的区别: 定位不同(小程序 ...
- Csrf_token ||| CSRF跨站请求伪造
# 注: 部分内容参考网上,侵删 CSRF(Cross-site request forgery) 跨站请求伪造,是一种对网站的恶意利用 它会通过伪装成受信任用户的请求来利用受信任的网站来获取一 ...
- oracle导入导出功能
1.普通版:oracle导入导出功能:导出exp 用户名/密码@SID file=f:\xx.dmp owner=用户名 导入imp 用户名/密码@SID full=y file=f:\xx.dmp ...
- 我的第一篇博客:vue-cli配置项目
注意:在安装vue-cli之前一定要确保安装了node和vue 安装配置node:下载node(https://nodejs.org/en/)然后一路无脑安装 查看安装是否成功:node –versi ...
- C# WebSocket
WebSocket 协议用于完全双工的双向通信.这种通信,一般在浏览器和Web服务器之间进行,但仅交流那些支持使用WebSocket协议的客户端信息.WebSocket维持一个打开的连接. Tcp发送 ...