Windows内存体系(6) -- 彻底理解内存对齐
2017-12-24 23:40
405 查看
一、内存为什么要对齐
虽然所有的变量都是保存在特定地址的内存中,但最好还是按照内存对齐的要求来存储。这主要出于两个方面的原因考虑:平台原因:
不是所有的硬件平台(特别是嵌入式系统中使用的低端处理器)都能访问任意地址上的任意数据,某些硬件平台只能访问对齐的地址,否则会出现硬件异常。
性能原因:
如果数据存放在未对齐的内存空间中,则处理器访问变量时需要进行两次内存访问才能完整读取该变量的值,而对齐的内存访问仅需一次访问。
二、内存对齐的规则
对于结构(或联合)的各个成员,第一个成员位于偏移为0,以后每个数据成员的偏移量必须是#pragma pack指定的数值和结构(或联合)最大数据成员长度 这2个数值中较小的一个的倍数。
使用伪代码表示:
min(#pragma pack, 结构最大数据成员长度) * N
在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐也按照
#pragma pack指定的数值和结构(或联合)最大数据成员长度这2个数值中较小的一个进行。
如果没有使用
#pragma pack指令来显式的指定内存对齐的字节数,则按照默认字节数来对齐,各个平台的默认对齐规则如下:
32位CPU默认按照4字节对齐;64位CPU默认按照8字节对齐。
三、#pragma pack命令
#pragma pack(n) // 使用自定义n字节对齐 n可以为1,2,4,8,16 #pragma pack() // 使用缺省字节对齐 #pragma pack(show) // 在编译输出窗口以警告的形式显示出当前的内存以几个字节对齐
四、结构体内存对齐示例
在64位系统上编译下面的测试程序,已知在64位系统上各类型占用字节数如下:char 1字节 short 2字节 int 4字节 long 4字节 double 8字节 long long 8字节
示例代码如下:
#pragma pack(8) struct A { char s[5]; short c; int a; }; int main() { int i = sizeof(A); printf("%d", i); return 0; }
按照第二节所讲的内存对齐规则,分析如下:
因为结构体中最大的数据成员长度为int(即4字节),而且
#pragma pack(8)指令指定按照8字节对齐,所以
min(4,8) = 4,故我们可以知道结构体A按照4字节对齐。
下图是结构体A按照4字节对齐的内存布局(需要注意的是“内存不是填充在s5后面,而是填充在c后面”):
从图我们很容易知道
sizeof(A) = 12.
相关文章推荐
- sizeof理解01---内存对齐
- 内存对齐的方法理解
- 内存详解——理解 JVM 如何使用 Windows 和 Linux 上的本机内存
- 内存详解——理解 JVM 如何使用 Windows 和 Linux 上的本机内存
- 理解JVM如何使用Windows和Linux上的本机内存
- 理解JVM如何使用Windows和Linux上的本机内存
- 理解JVM如何使用Windows和Linux上的本机内存
- 理解 JVM 如何使用 Windows 和 Linux 上的本机内存
- windows和Linux内存的对齐方式
- 彻底理解内存概念- -
- Windows内存对齐问题
- 关于内存对齐的理解
- 内存详解-理解 JVM 如何使用 Windows 和 Linux 上的本机内存
- 理解 Windows CE .NET 中的文件系统体系结构(转)
- Windows系统理解---核心+CPU(物理或逻辑)+内存
- new/delete和malloc/free的区别,sizeof的理解和struct内存对齐
- 深入理解C语言内存对齐
- 又是考查内存对齐和指针理解, 简单东西。
- 理解 Windows CE .NET 中的文件系统体系结构(by Mike Hall)
- 对内存对齐的理解