结构体对齐(字节对齐)规则及大小计算
什么是字节对齐
这跟读取数据有关,cpu读取一次能读取到的内存大小跟数据总线的位数有关,如果数据总线为16位,那么cpu一次能够读取2字节;如果为32位那么cpu一次可以读取4字节,而读取数据是需要消耗时间的,为了提高效率,尽量让同一个数据(变量)能使用最少次数将其读取出来,那么解决办法就是要求每个数据(变量)在其自然边界上,比如说一个int类型的变量占4字节,那么在存储这个int变量的时候编译器会将让这个变量的起始地址能够被4整除,那么这样就不会导致这个int类型的变量明明没有超过数据总线位数(假设位32位)而需要cpu两次才能将其读取出来,这就是字节对齐。
为什么要进行字节对齐
上面也说了,为了提高效率。进行字节对齐还有另一个原因,那就是平台的原因,其实不是所有的硬件平台都能够访问任意地址上的任意数据,所以这就导致了进行字节对齐的必要性。尤其是结构体,结构体会包含不同类型的数据,如果不进行认为的(编译器做的事)字节对齐,那么就会导致数据不在他的自然边界上,会影响效率,甚至会引发硬件错误。
字节对齐规则
这里讲结构体对齐规则,结构体对齐包括字节对齐和结构的整体对齐。
1、字节对齐
字节对齐是针对结构体内的数据的对齐,程序员可以使用预处理指令# parama pack(n)来设定默认对齐数值,其中n值就是设置的大小(值位1,2,4,8...),数据成员本身也有一个字节大小,编译器会选择这两个中小的那个数值作为对齐大小。第一个数据成员从offset(偏移量)为0的地方开始存储。
比如:
#parama pack(2)
int a;
a 为整型,占4字节,比预处理指令指定的2大,所以按照2来对齐,也就是说,存储a的起始地址必须要能被2整除。
2、整体对齐
整齐对齐也很简单,整体对齐也会比较两个数值的大小,第一个同样还是预处理指令指定的大小n,第二个是所有结构体的数据成员中字节最大的那个,编译器会选择两个中小的那个,我们设它为值m。选取之后,编译器会去查看结构体的最后一个数据成员存储之后的后一个地址是否为选取m的倍数,如果是m的倍数则什么都不需要做,如果不是,那么需要补齐,使得补齐之后的地址能被m整除(为m倍数)。
对齐举例
见如下的结构体。
#include<iostream>
using namespace std;#pragma pack(2)
struct AA{int a;char b;short c;char d;
};
#parama pack();
第一步:a占4字节,比预设的2大所以将2作为对齐大小,起始地址0是2倍数,所以a存储的位置区间为[0,3]。
第二步:b占1字节,比2小,所以将1作为对齐大小,如果紧挨着a存储b,那么起始地址为4,4是1的倍数,所以存储的b位置区
间为[4]。
第三步:c占2字节,所以对齐大小为2,如果紧挨着c存储,那么起始地址为5,而5不是2的倍数,6是2的倍数,所以需要补一
位,从6开始存储c,所以存储c的位置区间为[6,7]。
第四步:字节d占1字节,将1作为对齐大小,8是1的倍数,所以可以紧挨着c存储d,所以存储d的位置区间为[8]。
第五步:所有数据成员存储完后,需要进行整体对齐,数据成员中占最大字节的是int a,占4字节,比预设的2大,所以将2作为
对齐大小,而存储完最后一个数据成员d之后的地址为9,9不是2的倍数,需要补齐。
所以最后结构体占的区间为[0,9],也就是说结构体的size为10。
总结
因为是按照顺序存储结构体中的成员,所以即使结构体中的数据成员完全一样,而他们的相对位置顺序不一样的话,那么他们所占的大小也很可能不同。
比如下面的结构体和上面的结构体中的数据成员一模一样,只是顺序位置不一样,下面结构体的size却是8。
#include<iostream>
using namespace std;#pragma pack(2)
struct AA{int a;char b;char d;short c;
};
#parama pack();
结构体对齐(字节对齐)规则及大小计算相关推荐
- 转 结构体中字节对齐问题(转载)
struct MyStruct { double dda1; char dda; int type }; 对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少 ...
- C语言基础 - 结构体类型字节对齐总结
一.什么是字节对齐 在计算机中,内存空间是按照字节(1B = 8 bit)划分的,每一个字节都有一个编号,这就是字节的地址.理论上可以从任意起始地址访问任意数据类型的变量,但在实际使用中,访问特定数据 ...
- c# 结构体 4字节对齐_C语言程序员们常说的“内存对齐”,究竟有什么目的?
在C语言程序开发中,有时有经验的程序员会提起"内存对齐"一词,事实上,这也是C语言中结构体的 size 不等于它所有成员 size 之和的原因(C语言中的结构体的size,并不等于 ...
- c# 结构体 4字节对齐_【专题4:平时遇到的问题】 之 【3.由结构体字节对齐引发的通信故障】...
希望本是无所谓有,无所谓无的,这正如脚下的路,其实地上本没有路,走的人多了,也便成了路....原创不易,文章会持续更新,感谢您的关注 1.问题由来 MCU给上位机发送的一帧数据中,总是多一个字节,调试 ...
- c 定义结构体时提示应输入声明_C++|了解结构体的内存对齐(成员声明的顺序影响占用空间大小)...
我们使用的电子计算机绝大部分都是冯·诺依曼结构的机器,遵循"存储程序"的概念.数据处理以存储为前提,在编程中数据如何"存得进去,取得出来",并且符合空间.时间效 ...
- java解析c的结构体_解析C语言中结构体struct的对齐问题
首先看一下结构体对齐的三个概念值: 数据类型的默认对齐值(自身对齐): 1.基本数据类型:为指定平台上基本类型的长度.如在32位机器中,char对齐值为1,short为2,int,float为4,do ...
- c语言结构体变量所占字节计算,【C语言】结构体占用字节数及存储与空间分配...
我们都知道在数据类型中,char类型占1个字节,short占2个字节,int占4个字节,long占8个字节等等. 在计算结构体大小时需要考虑其内存布局,结构体在内存中存放是按单元存放的,每个单元多大取 ...
- C/C++结构体四字节数据对齐
为了避免混淆,做如下规定,以下代码若不加特殊说明都运行于32位平台,结构体的默认对齐值是8,各数据类型所占字节数分别为 char占一个字节 int占四个字节 double占八个字节. 两个例子 请问下 ...
- 字节对齐《c和指针》笔记--包含位域结构体的内存对齐(32bit,GCC)
最近使用开发的过程中出现了一个小问题,顺便记录一下原因和方法--字节对齐 C99划定int.unsigned int和bool可以作为位域类型.但编译器几乎都对此作了扩展,答应其它类型类型的存在. ...
最新文章
- Mysql中的递归层次查询(父子查询,无限极查询)
- mysql 分页测试,
- 13 种 JavaScript 代码技巧
- springMVC 过滤器与拦截器的执行顺序问题。springboot一样参考
- 基本概念—回归、分类、聚类
- hive与hbase的以及mongodb和cassandra区别整理
- ABAP 后台作业的一个状态查询工具
- 什么是 gRPC ?
- JDK源码(14)-Error、Exception
- CentOS网络设置 couldn‘t resolve host ‘mirrorlist.centos.org问题解决
- 【回顾】推荐系统的十二大评价指标总结
- 怎么做游戏打击感浅述
- Android模拟器读取GPS串口模拟器GPS数据
- 云桌面服务器+搭建,搭建自己的云桌面服务器
- 10种微信公众号的推广吸粉方法
- login.defs文件基础
- FlashBuilder找不到所需要的AdobeFlashPlayer调试器版本的解
- python自学行吗知乎_怎么自学python,大概要多久?
- Hyper-v集群高可用性配置
- 5G网络入门基础--5G网络的实现流程
热门文章
- python爬虫:找房助手V1.0-爬取58同城租房信息
- 熊猫数据集_使用大数据的熊猫
- 感冒发烧没想象中可怕:人体自我保护清除体内感染
- c语言课程设计三色球问题,C++三色球问题描述与算法分析
- 【14】婚礼片剪辑案例【15】电视剧片头剪辑案例
- mysql异地容灾备份开启log_bin
- springboot Nexus Repository Maven仓库搭建及使用
- Python文本挖掘练习(一)// 新闻摘要
- c atol()函数_atol()函数以及C ++中的示例
- 使用阿里云服务器三分钟搭建网站