【C/C++】内存对齐规则和实战
内存对齐规则和实战
这篇文章是我的平时的一个笔记修改后来的。这里主要介绍一下内存对齐的规则,以及提供一些实战一下。几篇我觉得比较好的详细的介绍内存对齐的作用什么的博文会在文末附上。
规则
在开始实战前,需要了解下规则。
首先了解变量的有效对齐值N
数据类型对齐值自身的对齐值:也就是基本数据类型的自身对齐值 如int 为4字节, char为1字节
指定对齐值:#pragma pack (value),这个宏中的value就是指定对齐值
结构体或类的自身对齐值:MAX(其成员变量自身对齐值)
数据成员、结构体和类的有效对齐值:MIN(自身对齐值,指定对齐值)
规则一
每个成员的起始地址应满足 “起始地址%N == 0”
规则二
结构体的有效对齐值要圆整(就是结构体成员变量占用的总长度需要是对结构体 有效对齐值 的整数倍)
<font color="blue>"总长度 % 有效对其值 == 0
实战
示例
先看一个例子运用一下规则,热热身。
可以先分析下,成员变量的有效对齐值是什么,然后要满足规则一和规则二,变量的存储地址要后移多少,最后算出的结构图的总长度是多少。(这里没有#pragma pack())
struct A
{
int a;
char b;
short c;
};
示例分析
- 首先确定每个成员的有效对齐值 因为没有指定对齐值 所以为自身数据类型的对齐值
a--4字节 b--1字节 c--2字节
- 起始地址必须满足规则一“起始地址%N = 0”
令起始地址位0x0000 按照变量的顺序存储<br>
变量a的起始地址 0x0000%4 = 0;满足条件 占用4个字节 0x0000--0x0003 占四个字节变量
b 的起始地址 是 0x0004%1 = 0满足条件 占用一个字节 就是0x0004
变量c 的起始地址 是 0x0005%2 !=0 所以起始地址要向后移位 直到满足条件位置 0x0006%2 = 0
满足条件 占用2字节 0x0006-- 0x0007
所以结构体总共占用了8字节
- 根据结构体的有效对齐值圆整
结构体的有效对齐值是 其成员中自身对齐值最大的那个值为4
由于8字节正好是4的整数倍 所有就是8字节
实战开始
上面分析了一次,下面可以进行实战了。下面加上了#pragma pack(),所以需要注意这里的有效对齐值是什么了,回顾前面MIN(自身对齐值,指定对齐值)。
实战1
#pragma pack(4)//指定对齐值
struct B
{
char b;
int a;
short c;
};
union C
{
int a[5];
char b;
double c;
};
struct D
{
int n;
C a;
char c[10];
};
实战2
#pragma pack(8)//指定对齐值
struct example1
{
short a;
long b;
};
struct example2
{
char c;
example1 struct1;
short e;
};
简单分析在下划线下面
内存单元从0开始编号
实战1分析
#pragma pack(4)//指定对齐值
struct B //10 + 2(圆整) = 12
{
char b;//[0]
int a;//[1]...[4]...[7]([1]...[4]表示地址后移到单元[4])
short c;//[8]...[9]
};
union C //20字节 联合体按成员所占最长单元算
{
int a[5];
char b;
double c;
};
struct D // 34+2(圆整) = 36
{
int n; // [0]...[3] (4个字节)
C a; // [4]...[23] (20字节)
char c[10]; // [24]...[33] (10字节)
};
实战2分析
#pragma pack(8)
struct example1//8
{
short a;//[0]...[1]
long b;//[2]...[4]...[7]
};
struct example2//14+2(圆整)=16
{
char c;//[0]
example1 struct1;// [1]...[4]...[11]
short e;//[12]...[13]
};
悄悄附上我的测试代码运行的截图

嗯 写了一些,还是以理解规则然后实战为主,附上详细的他人的博文,参考参考。
博文
【C/C++】内存对齐规则和实战的更多相关文章
- C语言中内存对齐规则讨论(struct)
C语言中内存对齐规则讨论(struct) 对齐: 现代计算机中内存空间都是按着byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地 ...
- 浅析内存对齐与ANSI C中struct型数据的内存布局-内存对齐规则
这些问题或许对不少朋友来说还有点模糊,那么本文就试着探究它们背后的秘密. 首先,至少有一点可以肯定,那就是ANSI C保证结构体中各字段在内存中出现的位置是随它们的声明顺序依次递增的,并且第一个字段的 ...
- 利用php unpack读取c struct的二进制数据,struct内存对齐引起的一些问题
c语言代码 #include <stdio.h> struct test{ int a; unsigned char b; int c; }; int main(){ FILE *fp; ...
- 关于sizeof()和内存对齐
PS补充:枚举类型的字节数为什么为4 百度知道回答: typedef enum e1{ MON, TUE, THI, }e; e1是一个数值,它的允许值范围是: MON,TUE,THI, 它的取值为其 ...
- c/c++学习系列之内存对齐
1.C++内存对齐规则 每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数).程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你 ...
- C/C++内存对齐详解
1.什么是内存对齐 还是用一个例子带出这个问题,看下面的小程序,理论上,32位系统下,int占4byte,char占一个byte,那么将它们放到一个结构体中应该占4+1=5byte:但是实际上,通过运 ...
- C++继承体系中的内存对齐
本篇随笔讨论一个比较冷门的知识,继承结构中内存对齐的问题,如今内存越来越大也越来越便宜,大部分人都已经不再关注内存对齐的问题了.但是作为一个有追求的技术人员,实现功能永远都是最基本的要求,把代码优化到 ...
- 重磅硬核 | 一文聊透对象在 JVM 中的内存布局,以及内存对齐和压缩指针的原理及应用
欢迎关注公众号:bin的技术小屋 大家好,我是bin,又到了每周我们见面的时刻了,我的公众号在1月10号那天发布了第一篇文章<从内核角度看IO模型的演变>,在这篇文章中我们通过图解的方式以 ...
- C++内存字节对齐规则
为什么要进行内存对齐以及对齐规则 C/C++—— 内存字节对齐规则 C++内存字节对齐规则
随机推荐
- 日常小节----unity小坑记(静态后不可移动和旋转)
当物体被置为静态时,模型网格是无法移动和旋转的,只有碰撞器可以. 也就是会出现当父物体不为静态,子物体为静态时,运行后旋转移动父物体,子物体模型网格不会跟随旋转移动,但子物体碰撞器会跟随旋转移动. 或 ...
- 两表拼接 pd.concat
a = pd.DataFrame([[1,2,3], [4,5,6], [7,8,9]],columns=['a','b','c']) b = pd.DataFrame([[11,23,45], [2 ...
- DEVOPS ROADMAP
- hydra 使用
Hydra介绍 Hydra是一个并行登录破解器,支持多种攻击协议.它非常快速和灵活,新模块易于添加.该工具使研究人员和安全顾问能够展示远程获得对系统未经授权的访问是多么容易. 它支持:Cisco AA ...
- C# PC版微信消息监听自动回复
最近有个微商客户需要搞个 个人微信监听群消息关键字并实现自动回复功能, 因为他有很多群 很多买家咨询的话 一个个回复太麻烦, 客户要求 比如群里有人发 关键字 产品1 则自动回复产品1的相关描述 ...
- [python] 初识 PyQt5
昨天想着用 Python 写个展示的 demo,之前打算熟悉一下 PyQt ,正好边学边做,学以致用. 主要的流程是在 cmd 下运行 .exe 并读取输出结果,运到的困难是如何实时回传数据以及修改图 ...
- Vue:不同页面之间的传递参数--params
在嵌套vue-router情况下,不同页面之间传递参数可以通过params实现.而params传参分为两种情况: 1.参数在url中显示 首先你要确定自己要传的参数,并在控制路由的文件中的Router ...
- [转帖]国内拉取google kubernetes镜像
国内拉取google kubernetes镜像 2019年04月19日 01:19:03 willblog 阅读数 4231 标签: kubernetes 更多 个人分类: kubernetes ...
- SQL2000中文版打不上SP4提示用户验证没有通过
https://jingyan.baidu.com/article/7f41ececf24841593d095cd8.html 解决方法: 在安装SQL Server SP4,有时候会出现:无论用wi ...
- 可取消可报告进度的Task
using System; using System.Threading; using System.Threading.Tasks; using System.Windows; namespace ...