内存变量边界对齐

一、什么是内存对齐

(1)   原理

a)  编译器按照成员列表的顺序给每个成员分配内存.

b)  当成员需要满足正确的边界对齐时,成员之间用额外字节填充.

c)  结构体的首地址必须满足结构体中边界要求最为严格的数据类型所要求的地址.

d)  结构体的大小为其最宽基本类型的整数倍.

(2)   程序设计

 1 #include<iostream>
 2
 3 #include<cstdio>
 4
 5 #include<string>
 6
 7 using namespace std;
 8
 9 struct node1
10
11 {
12
13       char c;
14
15       char b;
16
17       int a;
18
19 }n1;
20
21 struct node2
22
23 {
24
25       char c;
26
27       int a;
28
29       char b;
30
31 }n2;
32
33 int main()
34
35 {
36
37       //内存大小
38
39       int size1=sizeof(node1);
40
41       int size2=sizeof(node2);
42
43       printf("%d %d\n",size1,size2);
44
45       //具体地址
46
47       //node1
48
49       cout<<(long long)(void*)&n1.c-(long long)(void*)&n1<<endl;
50
51       cout<<(long long)(void*)&n1.b-(long long)(void*)&n1<<endl;
52
53       cout<<(long long)(void*)&n1.a-(long long)(void*)&n1<<endl;
54
55       //node2
56
57       cout<<(long long)(void*)&n2.c-(long long)(void*)&n2<<endl;
58
59       cout<<(long long)(void*)&n2.a-(long long)(void*)&n2<<endl;
60
61       cout<<(long long)(void*)&n2.b-(long long)(void*)&n2<<endl;
62
63       return 0;
64
65 }

(3)   结果

实验显示结果为

(4)   分析

a)    node1和node2的成员相同,但成员的顺序不一样,所以总体占用的空间不一样,验证了编译器按照成员列表的顺序给每个成员分配内存。

b)   对于node1和node2,分别输出每个成员的占用空间,发现char c和char b顺序紧挨时,各占据一个字节;char a 和char b相隔时,各占据4个字节。验证了当成员需要满足正确的边界对齐时,成员之间用额外字节填充.

c)    实验表明,内存变量是按边界对齐。

二、为什么要按边界对齐(转载请注明出处:http://blog.csdn.net/acs713/article/details/25040389

从处理器的角度来看,需要尽可能减少对内存的访问次数以实现对数据结构进行更加高效的操作。为什么呢?因为尽管处理器包含了缓存,但它在处理数据时还得读取缓存中的数据,读取缓存的次数当然是越少越好!如上图所示,在采用边界对齐的情况下,当处理器需要访问a_变量和b_变量时都只需进行一次存取(图中花括号表示一次存取操作)。若不采用边界对齐,a_变量只要一次处理器操作,而b_变量却至少要进行两次操作。对于b_,处理器还得调用更多指令将其合成一个完整的4字节,这样无疑大大降低了程序效率。

时间: 2024-08-30 01:02:18

内存变量边界对齐的相关文章

c++内存中字节对齐问题详解

一.介绍 什么是字节对齐 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐. 字节对齐的原因和作用 各个硬件平台对存储空间的处理上有很大的不同.一些平台对某些特定类型的数据只能从某些特定地址开始存取.比如有些架构的CPU在访问 一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字

c++内存中字节对齐问题详解[转载]

一.什么是字节对齐,为什么要对齐?     现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐.     对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同.一些平台对某些特定类型的数据只能从某些特定地址开始存取.比如有些架构的CPU在访问 一个没有进行对齐的变量的时候会发生错误,那么在

OpenCV源码之内存分配-指针对齐

首先,为什么要指针对齐(Pointer Alignment)? 指针对齐有时候非常重要,因为许多硬件相关的东西在对齐上存在限制.在有些系统中,某种数据类型只能存储在偶数边界的地址处. 例如,在经典的 SPARC架构(以及经典的ARM)上,你不能从奇数地址读取一个超过1字节的整型数据.尝试这么做将会立即终止程序,并伴随着总线错误.而在X86架构上,CPU硬件处理了这个问题,只是这么做将会花费更多时间:通常RISC架构是不会为你做这些.举例如下: char c; char *Pc = &c; int

智能合约从入门到精通:Solidity语法之内存变量的布局和状态变量的存储模型

简介:在前面我们已经讲过Solidity语言的一些语法内容,在矩阵元JUICE开放平台的JIDE开发时,一定要注意Layout in Memory和Layout of State Variables in Storage,即内存变量的布局和状态变量的存储模型.内存变量的布局(Layout in Memory) Solidity预留了3个32字节大小的槽位: 0-64:哈希方法的暂存空间(scratch space) 64-96:当前已分配内存大小(也称空闲内存指针(free memory poi

聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数]

聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数] 较之传统通过App.config和Web.config这两个XML文件承载的配置系统,.NET Core采用的这个全新的配置模型的最大一个优势就是针对多种不同配置源的支持.我们可以将内存变量.命令行参数.环境变量和物理文件作为原始配置数据的来源,如果采用物理文件作为配置源,我们可以选择不同的格式(比如XML.JSON和INI等) .如果这些默认支持的配置源形式还不能满足你的需求,我们还可以通过注册自定义ConfigurationSour

.NET Core采用的全新配置系统[5]: 聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数]

较之传统通过App.config和Web.config这两个XML文件承载的配置系统,.NET Core采用的这个全新的配置模型的最大一个优势就是针对多种不同配置源的支持.我们可以将内存变量.命令行参数.环境变量和物理文件作为原始配置数据的来源,如果采用物理文件作为配置源,我们可以选择不同的格式(比如XML.JSON和INI等) .如果这些默认支持的配置源形式还不能满足你的需求,我们还可以通过注册自定义ConfigurationSource的方式将其他形式数据作为我们的配置来源. [ 本文已经同

结构体边界对齐

结构体边界对其是一个老生常谈的话题了,网上的解释非常多,但大多偏重于讲步骤,对于每一步的原因都有点不清楚的地方,下面结合网上的讲解和自己的理解谈谈结构体对齐,不一定正确. 1.什么是结构体对齐. struct A{ char  a: char b: int c: char  d: } 对于上面的这个结构体,假设机器字长32位(4字节),那么该结构体变量占用的空间并非1+1+4+1=7,而是1+3+4+1+3=12.编译器自动将c的起始位置调整到第4个字节处,并在结构体最后加了3个字节,这种编译器

C语言结构体变量字节对齐问题总结

结构体字节对齐 在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题.从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但是事实上不是如此,实际上访问特定类型的变量只能在特定的地址访问,这就需要各个变量在空间上按一定的规则排列, 而不是简单地顺序排列,这就是内存对齐. 内存对齐的原因: 1)某些平台只能在特定的地址处访问特定类型的数据: 2)提高存取数据的速度.比如有的平台每次都是从偶地址处读取数据,对于一个int型的

【原创】_INTSIZEOF 内存按照int对齐

#include <stdarg.h> 里面定义了如下宏 #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) 主要作用是用于将变量n按照int大小内存地址对齐,返回内存对齐后n的大小(一般>=sizeof(n)) 公式的计算方式如下过程:是转载过来了的 对于两个正整数 x, n 总存在整数 q, r 使得 x = nq + r, 其中  0<= r <n