内存对齐规则和实战

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

规则

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

首先了解变量的有效对齐值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. 深入解析d3弦图

    记得上次看d3应该是1年前的事情了,当时还一边看一边写了d3(v5.7)的一个学习笔记:https://www.cnblogs.com/eco-just/tag/d3/ 后来转战three.js就没继 ...

  2. git-忽略不想提交到git的文件

    在代码目录下建立.gitignore文件: .gitignore (用记事本另存可以保存这个名字),配置上要忽略的文件或者文件夹,然后提交到git 上就可以了.

  3. kubernetes安装dashboard步骤 【h】

    本篇文章参考kubernetes---dashboardv1.8.3版本安装详细步骤及 kubernetes-dashboard(1.8.3)部署与踩坑这两篇文章,详细写了自己部署过程中的操作.遇到的 ...

  4. svn 创建外部链接

    背景: 之前的服务器项目<杀戮链条>,服务器工程中的common目录需要在多个子工程中共享,为了统一,所以只保留一个common目录,在子工程中采用外部链接的方法共享到工程中 1.  打开 ...

  5. 深入理解C语言-函数指针

    函数指针在C++中有着重要的应用,函数的函数名其本质就是代表一个地址,这个地址叫做函数入口,得到这个地址就可以对这个函数进行各种操作. 函数类型基础 函数三要素: 名称.参数.返回值 C语言中的函数有 ...

  6. Linux Pycharm 添加图标到root账户桌面

    1. 去官网下载pycharm程序 2. 解压缩下载到的tar包 3. 在/usr/share/applications目录下新建一个pycharm.desktop, 写入内容如下, 注意红色字体需要 ...

  7. Java实现链队

    一.分析 队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端删除元素.允许插入的一端称为队尾,允许删除的一端称为队头. 链队是指采用链式存储结构实现的队列,它的基本操作如下: 1.初始 ...

  8. C#常见面试题(一)——try-catch-finally-return

    面试常会被问及try-catch-finally,现在做一下总结: 第一.不管有没有出现异常,finally块中代码都会执行. 第二.finally 代码块中不能有return. 第三.如果try 或 ...

  9. MySQL8在CentOS7上的安装

    Install_CentOS7_MySQL8_binary.sh #!/bin/bash MySQL_Package=mysql-8.0.16-linux-glibc2.12-x86_64.tar.x ...

  10. 并不对劲的复健训练-p3674

    题目大意 给出序列$ a_1,...,a_n $ ( $ n\leq10^5,a\leq 10^5 $ ),有\(m\) ( \(m\leq 10^5\))个以下三类询问: (1)给出\(l,r,k\ ...