内存对齐规则和实战

这篇文章是我的平时的一个笔记修改后来的。这里主要介绍一下内存对齐的规则,以及提供一些实战一下。几篇我觉得比较好的详细的介绍内存对齐的作用什么的博文会在文末附上。

规则

在开始实战前,需要了解下规则。

首先了解变量的有效对齐值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;
};

示例分析

  1. 首先确定每个成员的有效对齐值 因为没有指定对齐值 所以为自身数据类型的对齐值
  a--4字节  b--1字节  c--2字节
  1. 起始地址必须满足规则一“起始地址%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字节
  1. 根据结构体的有效对齐值圆整
  	结构体的有效对齐值是 其成员中自身对齐值最大的那个值为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++】内存对齐规则和实战的更多相关文章

  1. C语言中内存对齐规则讨论(struct)

    C语言中内存对齐规则讨论(struct) 对齐: 现代计算机中内存空间都是按着byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地 ...

  2. 浅析内存对齐与ANSI C中struct型数据的内存布局-内存对齐规则

    这些问题或许对不少朋友来说还有点模糊,那么本文就试着探究它们背后的秘密. 首先,至少有一点可以肯定,那就是ANSI C保证结构体中各字段在内存中出现的位置是随它们的声明顺序依次递增的,并且第一个字段的 ...

  3. 利用php unpack读取c struct的二进制数据,struct内存对齐引起的一些问题

    c语言代码 #include <stdio.h> struct test{ int a; unsigned char b; int c; }; int main(){ FILE *fp; ...

  4. 关于sizeof()和内存对齐

    PS补充:枚举类型的字节数为什么为4 百度知道回答: typedef enum e1{ MON, TUE, THI, }e; e1是一个数值,它的允许值范围是: MON,TUE,THI, 它的取值为其 ...

  5. c/c++学习系列之内存对齐

    1.C++内存对齐规则 每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数).程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你 ...

  6. C/C++内存对齐详解

    1.什么是内存对齐 还是用一个例子带出这个问题,看下面的小程序,理论上,32位系统下,int占4byte,char占一个byte,那么将它们放到一个结构体中应该占4+1=5byte:但是实际上,通过运 ...

  7. C++继承体系中的内存对齐

    本篇随笔讨论一个比较冷门的知识,继承结构中内存对齐的问题,如今内存越来越大也越来越便宜,大部分人都已经不再关注内存对齐的问题了.但是作为一个有追求的技术人员,实现功能永远都是最基本的要求,把代码优化到 ...

  8. 重磅硬核 | 一文聊透对象在 JVM 中的内存布局,以及内存对齐和压缩指针的原理及应用

    欢迎关注公众号:bin的技术小屋 大家好,我是bin,又到了每周我们见面的时刻了,我的公众号在1月10号那天发布了第一篇文章<从内核角度看IO模型的演变>,在这篇文章中我们通过图解的方式以 ...

  9. C++内存字节对齐规则

    为什么要进行内存对齐以及对齐规则 C/C++—— 内存字节对齐规则 C++内存字节对齐规则

随机推荐

  1. 【Linux】CentOS7安装mysql5.7

    官网下载地址 ​ https://dev.mysql.com/downloads/file/?id=471503 ​ 本文所用MySQL版本为5.7.19; 上传包 ​ 将mysql-5.7.19-1 ...

  2. Linux 查看修改SWAP大小

    1  查看swap 空间大小(总计):     # free -m          默认单位为k, -m 单位为M                total       used       fre ...

  3. 还原Master数据库后SQLSERVER的服务无法开启

    如果还原Master数据库后,SQLSERVER的服务无法开启,请注意是否因为其他的系统数据库在Master备份中记录的路径与现在的路径不一致导致的. 如果是,可以在cmd中执行“NET START ...

  4. mac编译openJDK8

    买了<深入理解Java虚拟机> 周志明著这本书一直没有看,我们的程序都用JVM在跑,所以学习java必须掌握JVM,才能理解我们对象到底干嘛了.   1.为什么要编译JDK 想要一探JDK ...

  5. vue-router跳转相同路径报错

    import Vue from 'vue' import Router from 'vue-router' // hack router push callback const originalPus ...

  6. Python全栈开发之7、面向对象编程进阶-类属性和方法、异常处理和反射

    一.类的属性 1.@property属性 作用就是通过@property把一个方法变成一个静态属性 class Room: def __init__(self,name,length,width,he ...

  7. cm api

    cm API:https://github.com/cloudera/cm_api/tree/master/python/examples/auto-deploy#看集群有几个clustercurl ...

  8. Docker 运行 MYSQL 数据库的总结

    公司里面要求做一个小demo 学习java相关的东西 然后使用了mysql数据库 很早之前做过mysql的容器化运行. 现在想想已经忘记的差不多了  所以这里总结一下 docker化运行mysql数据 ...

  9. Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge 树上倍增

    E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...

  10. DRF 认证 权限 视图 频率

    认证组件 使用:写一个认证类,继承BaseAuthentication 在类中写authenticate方法,把request对象传入 能从request对象中取出用户携带的token根据token判 ...