C++常见面试问题之内存对齐

一、内存对齐是什么

1.内存对齐是什么

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

复制代码
//32位系统
#include<stdio.h>
struct{
    int x;
    char y;
}s;

int main()
{
    printf("%d\n",sizeof(s);  // 输出8
    return 0;
}

现代计算机中内存空间都是按照 byte 划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但是实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。

2.内存对齐规则

那么接下来我们来说一下结构体中内存对齐的规则:

1.对于结构体中的各个成员,第一个成员位于偏移为 0 的位置,以后的每个数据成员的偏移量必须是min(#pragma pack()制定的数,数据成员本身长度)的倍数。 n= 1,2,4,8,16

每个特定平台上的编译器都有自己的默认"对齐系数"(也叫对齐模数)。gcc中默认#pragma pack(4),可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这一系数。

2.在所有的数据成员完成各自对齐之后,结构体或联合体本身也要进行对齐,整体长度是 min(#pragma pack())制定的数,长度最长的数据成员的长度)的倍数

二、为什么内存对齐

内存对齐的作用:

1.经过内存对齐之后,CPU 的内存访问速度大大提升 。因为 CPU 把内存当成是一块一块的,块的大小可以是2,4,8,16 个字节,因此 CPU 在读取内存的时候是一块一块进行读取的,块的大小称为内存读取粒度。比如说CPU 要读取一个 4 个字节的数据到寄存器中(假设内存读取粒度是 4),如果数据是从0字节开始的,那么直接将0-3 四个字节完全读取到寄存器中进行处理即可。

2.如果数据是从1字节开始的,就首先要将前 4 个字节读取到寄存器,并再次读取 4-7 个字节数据进入寄存器,接着把0字节,5,6,7字节的数据剔除,最后合并 1,2,3,4 字节的数据进入寄存器,所以说,当内存没有对齐时,寄存器进行了很多额外的操作,大大降低了 CPU 的性能 。 3.另外,还有一个就是,有的 CPU 遇到未进行内存对齐的处理直接拒绝处理,不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。所以内存齐还有利于平台移植

相关推荐
毕设源码余学姐22 分钟前
计算机毕设 java 中医药药材分类采购网站 SSM 框架药材交易平台 Java 开发的分类采购与订单管理系统
java·开发语言·课程设计
降临-max1 小时前
JavaSE---网络编程
java·开发语言·网络·笔记·学习
湖边看客1 小时前
antd x6 + vue3
开发语言·javascript·vue.js
小离a_a1 小时前
flex垂直布局,容器间距相等
开发语言·javascript·ecmascript
傻啦嘿哟2 小时前
物流爬虫实战:某丰快递信息实时追踪技术全解析
java·开发语言·数据库
码力码力我爱你2 小时前
Harmony OS C++实战
开发语言·c++
茄子凉心2 小时前
android 开机启动App
android·java·开发语言
Vect__2 小时前
别再只懂 C++98!C++11 这7个核心特性,直接拉开你与普通开发者的差距
c++
低客的黑调2 小时前
了解JVM 结构和运行机制,从小白编程Java 大佬
java·linux·开发语言
想唱rap2 小时前
C++ map和set
linux·运维·服务器·开发语言·c++·算法