C++ 结构体的对齐
flyfish
文章目录
- C++ 结构体的对齐
- 一 非对齐方式
- 二 对齐方式
- 示例1
- 示例2
- 三 对齐到指定字节数 boundary
一 非对齐方式
也就是按照1字节对齐
#pragma pack(1)
typedef unsigned char BYTE;
typedef struct message
{
BYTE a[4];
BYTE b[2];
BYTE *c;
BYTE d[4];
} MESSAGE;
int main(void)
{
MESSAGE m;
m.c=new BYTE[200];
std::cout<<sizeof(MESSAGE)<<":"<<sizeof(m)<<"\n";
std::cout<<sizeof(m.a)<<":"<<sizeof(m.b)<<":"<<sizeof(m.c)<<":"<< sizeof(m.d);
delete[] m.c;
return 0;
}
18:18
4:2:8:4
指针的大小不依赖于它们所指向的数据类型,在64位系统下都是8
#pragma
是一个特殊用途的指令,用于打开或关闭某些特性。#pragma pack(1)
按照1字节对齐
二 对齐方式
说规则太生硬,可以看例子
示例1
typedef struct message
{
BYTE a[7]; //7
BYTE b[2]; //2
BYTE c[9]; //11
int d[1]; //4
} MESSAGE;
看下内存地址分布
BYTE a[7]: C0 - C6
BYTE b[2]: C7 - C8
BYTE c[9]: C9 - D3
int d[1] : D4
C9到D3 补了两个字节,也就是BYTE c[9]之后多了两个字节。共 9+2=11
个字节
7+2+11+4=24 一共24个字节
示例2
typedef struct message
{
BYTE a[4]; //4
BYTE b[2]; //4
double c; //8
BYTE d[4]; //8
} MESSAGE;
BYTE b[2] 后补了2个字节
BYTE d[4] 后补了4个字节
4+4+8+8 一共24个字节
计算机使用word boundary的概念来存储structure 。word boundary的大小(sizeof)与机器有关。
处理器不会一次从内存中读取一个字节。它一次读取一个word 。
例如在32位处理器中,它一次可以访问4个字节,这意味着word 为4字节。
在64位处理器中,它一次可以访问8个字节,这意味着word 为8字节。
将structure 补上字节数用于节省CPU周期数。
三 对齐到指定字节数 boundary
默认4字节
typedef struct message
{
BYTE a[7];
BYTE b[2];
BYTE c[9];
int d[1];
} MESSAGE;
int main(void)
{
MESSAGE m={};
std::cout<<sizeof(MESSAGE)<<":"<<sizeof(m)<<":"<<sizeof(int*) <<":"<<alignof(MESSAGE)<<"\n";
std::cout<<sizeof(m.a)<<":"<<sizeof(m.b)<<":"<<sizeof(m.c)<<":"<< sizeof(m.d);
return 0;
}
使用alignas 对齐到16字节 boundary
typedef struct alignas(16) message
{
BYTE a[7];
BYTE b[2];
BYTE c[9];
int d[1];
} MESSAGE;