环境:

  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++字节对齐与位域的更多相关文章

  1. C语言基础--结构体对齐,位域,联合体

    结构体对齐 1--结构体对齐的原因与意义 许多计算机系统对基本数据类型的可允许地址做出了一些限制,要求某种类型的对象的地址必须是某个值K(通常是2,4,8)的倍数,而这个k则被称为该数据类型的对齐模数 ...

  2. sizeof(结构体)和内存对齐以及位域

    Win32平台下的微软C编译器的对齐策略: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除: 备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该 ...

  3. c/c++ 字节对齐

    c 字节对齐 概念: 结构体里会包括各种类型的成员,比如int char long等等,它们要占用的空间不同,系统为一个结构体开辟内存空间时,会有2种选择. 第一种:节省空间的方案,以上面的列子来说的 ...

  4. C语言字节对齐问题详解

    引言 考虑下面的结构体定义: typedef struct{ char c1; short s; char c2; int i; }T_FOO; 假设这个结构体的成员在内存中是紧凑排列的,且c1的起始 ...

  5. C/C++结构体字节对齐详解

    结构体的sizeof先看一个结构体:struct S1{    char c;    int i;}; sizeof(S1)在VC6中按默认设置得到的结果为8.我们先看看sizeof的定义——size ...

  6. C语言字节对齐问题详解(对齐、字节序、网络序等)

    首先说明一下,本文是转载自: http://www.cnblogs.com/clover-toeic/p/3853132.html 博客园用的少,不知道怎么发布转载文章,只能暂时这样了. 引言 考虑下 ...

  7. C++进阶3.字节对齐 联合

    C++进阶3.字节对齐 联合 20131011 多益和金山笔试 知识漏洞 20131011 前言: 今天下午是多益网络的笔试,整体感觉还好,但是找到很多的知识漏洞.一直笔试到6:00,然后紧张的从会生 ...

  8. <摘录>字节对齐(强制对齐以及自然对齐)

    struct {}node; 32为的x86,window下VC下sizeof(node)的值为1,而linux的gcc下值为0: 一.WINDOWS下(VC--其实GCC和其原理基本一样,象这种问题 ...

  9. C语言字节对齐问题详解【转】

    引言 转自:http://www.cnblogs.com/clover-toeic/p/3853132.html 考虑下面的结构体定义: 1 typedef struct{ 2 char c1; 3 ...

随机推荐

  1. Python36 二进制文件读写问题

    在Python36中写如下代码: __author__ = '-------'#-*- coding: utf-8 -*-import struct fo = open("myfile.tx ...

  2. JAVA Number与Math类

    Number类: 当要用到数字的时候,我们除了使用内置数据类型byte,int,double等来声明,我们还把它声明为一个对象: 所有的包装类(Integer.Long.Byte.Double.Flo ...

  3. python中对文件、文件夹,目录的基本操作

    一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法.1.得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()2.返回指定目录下的所有文件和目 ...

  4. Shell 字符串处理

    字符串处理方式 计算字符串长度 获取子串在字符串中的索引位置 计算子串长度 抽取(截取)字串 1.计算字符串长度,有两种方式 $ ${#string} $ expr length "$str ...

  5. python2入门(3)

    六.python列表(List) python最常见的序列类型python列表List使用[]表示,元素之间以逗号分隔,元素类型不需要相同 内置操作: list = [1,2,3,'four'] li ...

  6. 第四次Scrum编码冲刺

    第四次Scrum编码冲刺!!!! 一.总体任务: 本次冲刺是完成对图书馆管理系统的最后三个功能的实现------管理员对用户授权.用户注销和用户查询 二.个人任务及完成情况:    本人本次的任务是实 ...

  7. Git bash命令

    1.最开始使用git的时候, git remote -v 查看远程仓库 报了一个错误fatal: not a git repository (or any of the parent director ...

  8. 在java中浅谈Math类中的常用方法

    通过最近的学习,学到了一些的Math类中的常见方法 package org.stm.demo; public class Test { public static void main(String[] ...

  9. python 一些魔法

    1. range(object): """ range(stop) -> range object range(start, stop[, step]) -> ...

  10. yii2 rules 验证规则

    yii2  框架定义的约束 public $builtInValidators = [ 'boolean' => 'yii\validators\BooleanValidator', 'capt ...