内存对齐规则和实战

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

规则

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

首先了解变量的有效对齐值N

  • 数据类型对齐值自身的对齐值:也就是基本数据类型的自身对齐值 如int 为4字节, char为1字节

  • 指定对齐值:#pragma pack (value),这个宏中的value就是指定对齐值

  • 结构体或类的自身对齐值:MAX(其成员变量自身对齐值)

  • 数据成员、结构体和类的有效对齐值:MIN(自身对齐值,指定对齐值)

规则一

每个成员的起始地址应满足 “起始地址%N == 0”

规则二

结构体的有效对齐值要圆整(就是结构体成员变量占用的总长度需要是对结构体 有效对齐值 的整数倍)

<font color="blue>"总长度 % 有效对其值 == 0


实战

示例

先看一个例子运用一下规则,热热身。

可以先分析下,成员变量的有效对齐值是什么,然后要满足规则一和规则二,变量的存储地址要后移多少,最后算出的结构图的总长度是多少。(这里没有#pragma pack())

  1. struct A
  2. {
  3. int a;
  4. char b;
  5. short c;
  6. };

示例分析

  1. 首先确定每个成员的有效对齐值 因为没有指定对齐值 所以为自身数据类型的对齐值
  1. a--4字节 b--1字节 c--2字节
  1. 起始地址必须满足规则一“起始地址%N = 0”
  1. 令起始地址位0x0000 按照变量的顺序存储<br>
  2. 变量a的起始地址 0x0000%4 = 0;满足条件 占用4个字节 0x0000--0x0003 占四个字节变量
  3. b 的起始地址 0x0004%1 = 0满足条件 占用一个字节 就是0x0004
  4. 变量c 的起始地址 0x0005%2 !=0 所以起始地址要向后移位 直到满足条件位置 0x0006%2 = 0
  5. 满足条件 占用2字节 0x0006-- 0x0007
  6. 所以结构体总共占用了8字节
  1. 根据结构体的有效对齐值圆整
  1. 结构体的有效对齐值是 其成员中自身对齐值最大的那个值为4
  2. 由于8字节正好是4的整数倍 所有就是8字节

实战开始

上面分析了一次,下面可以进行实战了。下面加上了#pragma pack(),所以需要注意这里的有效对齐值是什么了,回顾前面MIN(自身对齐值,指定对齐值)。

实战1
  1. #pragma pack(4)//指定对齐值
  2. struct B
  3. {
  4. char b;
  5. int a;
  6. short c;
  7. };
  8. union C
  9. {
  10. int a[5];
  11. char b;
  12. double c;
  13. };
  14. struct D
  15. {
  16. int n;
  17. C a;
  18. char c[10];
  19. };
实战2
  1. #pragma pack(8)//指定对齐值
  2. struct example1
  3. {
  4. short a;
  5. long b;
  6. };
  7. struct example2
  8. {
  9. char c;
  10. example1 struct1;
  11. short e;
  12. };

简单分析在下划线下面


内存单元从0开始编号

实战1分析
  1. #pragma pack(4)//指定对齐值
  2. struct B //10 + 2(圆整) = 12
  3. {
  4. char b;//[0]
  5. int a;//[1]...[4]...[7]([1]...[4]表示地址后移到单元[4])
  6. short c;//[8]...[9]
  7. };
  8. union C //20字节 联合体按成员所占最长单元算
  9. {
  10. int a[5];
  11. char b;
  12. double c;
  13. };
  14. struct D // 34+2(圆整) = 36
  15. {
  16. int n; // [0]...[3] (4个字节)
  17. C a; // [4]...[23] (20字节)
  18. char c[10]; // [24]...[33] (10字节)
  19. };
实战2分析

  1. #pragma pack(8)
  2. struct example1//8
  3. {
  4. short a;//[0]...[1]
  5. long b;//[2]...[4]...[7]
  6. };
  7. struct example2//14+2(圆整)=16
  8. {
  9. char c;//[0]
  10. example1 struct1;// [1]...[4]...[11]
  11. short e;//[12]...[13]
  12. };

悄悄附上我的测试代码运行的截图


嗯 写了一些,还是以理解规则然后实战为主,附上详细的他人的博文,参考参考。

博文

【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. (转载)详解Javascript中prototype属性(推荐)

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...

  2. Java泛型(8):自限定&参数协变

    自限定 自限定将强制泛型当做自己的边界参数来使用.自限定所做的,就是要求在继承关系中,像下面这样使用这个类: class A extends SelfBounded<A> {} 它的意义是 ...

  3. JavaScript高程第三版笔记-DOM扩展

    在那个刀耕火种的年代,用过jQuery的都体会到了jQuery带来的便捷,尤其是元素选择器. jQuery(www.jquery.com)的核心就是通过 CSS 选择符查询 DOM 文档取得元素的引用 ...

  4. Kaggle初体验之泰坦尼特生存预测

    Kaggle初体验之泰坦尼特生存预测 学习完了决策树的ID3.C4.5.CART算法,找一个试手的地方,Kaggle的练习赛泰坦尼特很不错,记录下 流程     首先注册一个账号,然后在顶部菜单栏Co ...

  5. C语言链表之两数相加

    题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...

  6. getopts的使用 + 创建空目录

    1.getopts的经典例子 isRollback= rollbackVer="" targetGroup="" actionType="" ...

  7. 第五周课程总结&实验报告(四)

    第五周课程总结 本周主要学习了 1.抽象类 抽象类的定义格式 abstract class抽象类名称{ 属性; 访问权限返回值类型方法名称(参数){ //普通方法 [return返回值]; } 访问权 ...

  8. [转帖]java注解与注释注解区别

    https://baijiahao.baidu.com/s?id=1615942718081024481&wfr=spider&for=pc 还需要仔细看一下书的 书里面都有. jav ...

  9. [转帖]SSL延迟有多大?

    SSL延迟有多大? http://www.ruanyifeng.com/blog/2014/09/ssl-latency.html 转帖 作者: 阮一峰 日期: 2014年9月24日 感谢 腾讯课堂N ...

  10. 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 ...