内存字节对齐规则与作用

时间:2023-01-11 17:54:22

作用:

1、 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2、 性能原因:经过内存对齐后,CPU的内存访问速度大大提升。

规则:

1.数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

2.结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

3.收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.

/*****************************************
> File Name : test1.cpp
> Description : 内存字节对齐规则
64bit win7 VS2013
> Author : linden
> Date : 2016-02-28
*******************************************/


#include "stdafx.h"
#include "iostream"

using namespace std;

typedef struct _A
{
int i; //0~3
double d; //8~15 规则1
float f; //16~19 规则3,补齐20~23,凑满8的整数倍数
}A;

typedef struct _B
{
char c[2]; //0~1
int i; //4~7 规则1
double d; //8~15
short s; //16~17
A a; //24~47 规则2
}B;

int _tmain(int argc, _TCHAR* argv[])
{
cout << "sizeof(A) = " << sizeof(A) << endl; //24
cout << "sizeof(B) = " << sizeof(B) << endl; //48
return 0;
}
/*****************************************
> File Name : test2.cpp
> Description : 内存字节对齐规则
64bit win7 VS2013
> Author : linden
> Date : 2016-02-28
*******************************************/


#include "stdafx.h"
#include "iostream"

using namespace std;

typedef struct _A
{
char c; //0 4
int i; //4~7 4
short s; //8~9 4
}A;

typedef struct _B
{
short s; //0~1 2
char c; //2 2
int i; //4~7 4
A a; //12~23 12
}B;

int _tmain(int argc, _TCHAR* argv[])
{
cout << "sizeof(A) = " << sizeof(A) << endl; //12
cout << "sizeof(B) = " << sizeof(B) << endl; //20
return 0;
}
对A的解释:char占一个字节,起始偏移为0int4个字节,min(#pragma pack()指定的数,这个数据成员的自身长度) = 4
(VS默认8字节对齐),所以int4字节对齐,起始偏移必须为4的倍数,所以起始偏移为4,在char后编译器会添加3个字节的额外字节,
不存放任意数据。short2个字节,按2字节对齐,起始偏移为8,正好是2的倍数,无须添加额外字节。到此规则1的数据成员对齐结束,此时的内存状态为:
oxxx|oooo|oo
0123 4567 89 (地址)
(x表示额外添加的字节)
共占10个字节。还要继续进行结构本身的对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行,
A结构中最大数据成员长度为int,占4字节,而默认的#pragma pack 指定的值为8,所以结果本身按照4字节对齐,结构总大小必须为4的倍数,
需添加2个额外字节使结构的总大小为12 。此时的内存状态为:
oxxx|oooo|ooxx
0123 4567 89ab (地址)
到此内存对齐结束。A占用了12个字节而非7个字节。

参考链接: