C++内存对齐笔记
来源:互联网 发布:手机淘宝店如何招代理 编辑:程序博客网 时间:2024/06/05 11:47
Win8.1 64 Visual Studio 2013 Community 环境
内存对齐能够使CPU高效地从内存中进行数据读写,提高程序的运行效率。
何为内存对齐
内存对齐指数据存放的内存地址是否为对齐字节大小的倍数(一般为2的幂)。
实际上,C++中的基本数据类型默认的对齐字节为该数据类型的大小
如:char为1,short为2,int为4,float为4,double为8。
对象内存分布
struct和class中成员变量的内存对齐十分重要。如下代码:
struct X{ char a; int b; char c;};struct Y{ int a; char b; char c;};int main(){ cout << sizeof(X) << endl; cout << sizeof(Y) << endl; system("pause"); return 0;}
X,Y结构的成员大小都是6(4+1+1),但是输出结果却分别是12和8。其他造成不同的原因就是内存对齐。C++规定,对象的第一个成员的内存地址偏移量为0。
对于X:
a为char,占据内存的 0。
b为int,根据内存对齐,int的对齐字节为4,就是地址偏移必须为4的倍数,所以不能从地址1,2,3 开始放,只能放在[4,7]位。
c为char,放在 8 位。
总共是9位,对于整个结构体 X来说,也必须要内存对齐。对齐为成员中最大的字节4(int b),所以在末尾填充3个字节(padding),共计为12(4的倍数)。编译器加上这种填充,是为了当存在一个结构体数组时,仍能够正确的对齐,即只要定义此结构体的数组,并首个元素对齐,则整个数组元素都是对齐的
对于Y:
a为int ,占据[0,3]。
b为char,占据4
c为char ,占据5
总计6位,Y的对齐字节为4(int),所以自动填充两位变成8,构成4的倍数。
pragma pack(n)指令
使用#pragma pack(n)指令,可以改变对齐字节数。规定如下:
除了第一个成员变量,其余变量的内存地址偏移为min(n,sizeof(当前变量类型))。
整个结构的最终大小,必须是min(n,sizeof(最大变量类型))的倍数。
n为2的幂
从下面几个例子解释该命令:
首先没有#pragma pack命令
struct X{ char a; double b; short c;};
a为char,内存 0。
b为double,首地址必须在8的倍数,即[8,15]。
c为short,首地址2的倍数,即[16,17]。
共18位,结构大小必须是最大对齐字节倍数(8),即24。
输出大小为24。
使用#pragma pack(n)命令
#pragma pack(4)struct X{ char a; double b; short c;};
a为char,内存地址 0
b为double min(4,sizeof(double))=4 从4开始,[4,11]
c为short min=2,从12开始,[12,13]
最终大小14,min(4,8)=4,需要4的倍数,所以为16
输出大小为16。

#pragma pack(2)struct X{ char a; double b; short c;};
a 0
b min(2,8)=2, [2,9]
c min=2, [10 11]
共12字节,为min(2,8)=2的倍数,所以最终大小为12。

__declspec(align(m))指令
__declspec(align(m)) 确定整个结构的对齐字节,即调整整个结构的最终大小。
结构的最终大小,必须为max(m,sizeof(最大成员类型))的倍数。
m为2的幂
struct X{ short a; double b; int c;};
a [0,1]
b [8,15]
c [16 19]
共20字节,必须为8的倍数,所以最终为24字节

__declspec(align(16))struct X{ short a; double b; int c;};
同上,共20字节,max(16,8)=16,必须为16的倍数,所以最终大小为32字节。

__declspec(align(m))和#pragma pack(n)
两者同时出现时,由于__declspec(align(m))优先级较高,所以最终的结构大小按照 __declspec(align(m))的方式决定。
#pragma pack(2) __declspec(align(16))struct X{ short a; double b; int c;};
a [0,1]
b min(2,8)=2,[2,9]
c min=2, [10,13]
共14字节,结构大小需要为max(16,8)=16的倍数,所以为16

成员变量为结构体
__declspec(align())优先级高于#pragma pack
受__declspec(align())影响的结构体成员变量的对齐字节,由其__declspec(align())决定,不受#pragma pack影响
#pragma pack(push ,2) //所有结构体都受pack作用 __declspec(align(32))struct X{ char a; int b; double c;};__declspec(align(64))struct Y{ int a; double b; X c; int d;};int main(){ X x; Y y; cout << hex; cout << (long)&x.a << endl; cout << (long)&x.b << endl; cout << (long)&x.c << endl; cout << endl; cout << (long)&y.a << endl; cout << (long)&y.b << endl; cout << (long)&y.c << endl; cout << (long)&y.d << endl; cout << endl; cout << dec; cout << sizeof(X) << endl; cout << sizeof(Y) << endl; system("pause"); return 0;}
对于X
a 0
b min=2, [2,5]
c min=2, [6,13]
共14,max(8,32)=32,最终大小为32
对于Y
a [0,3]
b min=2, [4,11]
c 受__declspec(align(32))影响的结构体,
由于__declspec的优先级高,所以c必须为32位对齐(不受pack影响)
所以c最终为[32,63]
d min=2 ,[64,67]
共68字节,由于Y受__declspec(align(64)) 影响,必须为max(64,32)=64的倍数,最终大小为128字节。

- 《c专家编程》笔记--linux内存对齐
- 【C/C++】内存对齐
- C中的内存对齐
- C/C++内存对齐
- C/C++内存对齐
- c 内存对齐
- C/C++内存对齐
- C/C++内存对齐
- C/C++ 内存对齐
- C/C++ 内存对齐
- C内存对齐详解
- C语言 内存对齐
- c 内存对齐
- C/C++内存对齐
- C语言内存对齐
- C/C++内存对齐
- C/C++内存对齐
- C/C++内存对齐
- 对加密数据的高效的相似性搜索(一)
- CentOS-7下安装apache
- CRITICAL_SECTION http://blog.csdn.net/leowangzi/article/details/6572650
- hdu 1257
- Nginx的信号控制
- C++内存对齐笔记
- android典型代码系列(二十一)------根据文件后缀名获得对应的MIME类型
- LibGDX_1.3: Desktop 环境搭建:创建 Eclipse User Library,一劳永逸
- 剑指offer系列之八:跳台阶问题
- MyBatis入门学习教程
- 线性表
- python基础教程共60课-第4课输入
- eclipse/ADT 安装Gradle
- ORCAD层次化设计遇到Cannot descend from a schematic page that is not contained within the hierarchy