其实字节对齐是程序员与编译器共同完成的,内存对齐跟编译器、系统、CPU都有关系。
#include
#include "Fish.h"
struct Test2
{
char T2a[9];
int T2b;
double T2c;
char T2d;
};
int main(int argc,char *argv[])
{
printf("[%s,%d] size:%d T2aOf:%d T2bOf:%d T2cOf:%d T2dOf:%d \n",
__func__, __LINE__, sizeof(struct Test2),
alignof(Test2::T2a), alignof(Test2::T2b),
alignof(Test2::T2c), alignof(Test2::T2d));
}
$ ./demo
[main,23] size:32 T2aOf:1 T2bOf:4 T2cOf:8 T2dOf:1//这里32= 9 + (3) + 4 + 8 + 1 + (7) //这里括号内的是空间占位字节,这里将结构体对象的地址以8字节对齐是编译器保证的,比如他的开始地址为8,而T2a是char类型,是1字节对齐,所以其从8开始而8+9不能被四整除,所以加3可以被4整除,这这里9+(3)的位置就是T2b以4字节对齐的位置,而T2c是以8字节对齐的,9 + (3) + 4的位置刚好是T2c对齐地址,所以9+(3)+4+8,而char又是1字节对齐,所以这里9 + (3) + 4 + 8 + 1,而(7)是为了什么呢,其实7主要是考虑了结构体数族,
例如 struct Test2 TB[2]; 那么T[1]的地址也是8字节对齐,所以就有(7)
#include
#include "Fish.h"
#pragma pack(16)
struct Test2
{
char T2a[9];
int T2b;
double T2c;
char T2d;
};
#pragma pack()
int main(int argc,char *argv[])
{
printf("[%s,%d] size:%d T2aOf:%d T2bOf:%d T2cOf:%d T2dOf:%d \n",
__func__, __LINE__, sizeof(struct Test2),
alignof(Test2::T2a), alignof(Test2::T2b),
alignof(Test2::T2c), alignof(Test2::T2d));
}
/demo
[main,26] size:32 T2aOf:1 T2bOf:4 T2cOf:8 T2dOf:1
这里设置对齐方式为16字节对齐,但是根默认的是一样的
struct Test2
{
char T2a[9];
int T2b;
double T2c;
char T2d;
};
#pragma pack()
int main(int argc,char *argv[])
{
printf("[%s,%d] size:%d T2aOf:%d T2bOf:%d T2cOf:%d T2dOf:%d \n",
__func__, __LINE__, sizeof(struct Test2),
alignof(Test2::T2a), alignof(Test2::T2b),
alignof(Test2::T2c), alignof(Test2::T2d));
}
./demo
[main,26] size:22 T2aOf:1 T2bOf:1 T2cOf:1 T2dOf:1
struct alignas(64) Test2
{
char T2a[9];
int T2b;
double T2c;
char T2d;
};
int main(int argc,char *argv[])
{
printf("[%s,%d] size:%d T2aOf:%d T2bOf:%d T2cOf:%d T2dOf:%d \n",
__func__, __LINE__, sizeof(struct Test2),
alignof(Test2::T2a), alignof(Test2::T2b),
alignof(Test2::T2c), alignof(Test2::T2d));
}
$ ./demo
[main,24] size:64 T2aOf:1 T2bOf:4 T2cOf:8 T2dOf:1
#include
#include "Fish.h"
struct alignas(1) Test2
{
char T2a[9];
int T2b;
double T2c;
char T2d;
};
int main(int argc,char *argv[])
{
printf("[%s,%d] size:%d T2aOf:%d T2bOf:%d T2cOf:%d T2dOf:%d \n",
__func__, __LINE__, sizeof(struct Test2),
alignof(Test2::T2a), alignof(Test2::T2b),
alignof(Test2::T2c), alignof(Test2::T2d));
}
$ ./demo
[main,24] size:32 T2aOf:1 T2bOf:4 T2cOf:8 T2dOf:1
#include
#include "Fish.h"
struct Test2
{
char T2a[9];
int T2b;
double T2c;
char T2d;
}__attribute__((aligned(1)));
int main(int argc,char *argv[])
{
printf("[%s,%d] size:%d T2aOf:%d T2bOf:%d T2cOf:%d T2dOf:%d \n",
__func__, __LINE__, sizeof(struct Test2),
alignof(Test2::T2a), alignof(Test2::T2b),
alignof(Test2::T2c), alignof(Test2::T2d));
}
$ ./demo
[main,23] size:32 T2aOf:1 T2bOf:4 T2cOf:8 T2dOf:1
设置的值未能生效
#include
#include "Fish.h"
struct Test2
{
char T2a[9];
int T2b;
double T2c;
char T2d;
}__attribute__((aligned(64)));
int main(int argc,char *argv[])
{
printf("[%s,%d] size:%d T2aOf:%d T2bOf:%d T2cOf:%d T2dOf:%d \n",
__func__, __LINE__, sizeof(struct Test2),
alignof(Test2::T2a), alignof(Test2::T2b),
alignof(Test2::T2c), alignof(Test2::T2d));
}
$ ./demo
[main,23] size:64 T2aOf:1 T2bOf:4 T2cOf:8 T2dOf:1
以64位对齐,这里可以看出__attribute__(aligned(m))与alignas一样,可以将其对应的属相对齐在原来对齐基础上增大,但是不能减小
#include
#include "Fish.h"
struct Test2
{
char T2a[9];
int T2b;
double T2c;
char T2d;
}__attribute__((packed));
int main(int argc,char *argv[])
{
printf("[%s,%d] size:%d T2aOf:%d T2bOf:%d T2cOf:%d T2dOf:%d \n",
__func__, __LINE__, sizeof(struct Test2),
alignof(Test2::T2a), alignof(Test2::T2b),
alignof(Test2::T2c), alignof(Test2::T2d));
}
$ ./demo
[main,23] size:22 T2aOf:1 T2bOf:1 T2cOf:1 T2dOf:1
对齐方式以1字节对齐了,其实就是前面所说的,以对应结构体属性中的最小的对齐为对齐依据。
#include
#include "Fish.h"
#pragma pack(1)
struct alignas(64) Test1
{
char T1a[9];
int T1b;
double T1c;
char T1d;
};
struct Test2
{
char T2a[9];
int T2b;
double T2c;
char T2d;
};
#pragma pack()
int main(int argc,char *argv[])
{
printf("[%s,%d] size:%d T1aOf:%d T1bOf:%d T1cOf:%d T1dOf:%d \n",
__func__, __LINE__, sizeof(struct Test1),
alignof(Test1::T1a), alignof(Test1::T1b),
alignof(Test1::T1c), alignof(Test1::T1d));
printf("[%s,%d] size:%d T2aOf:%d T2bOf:%d T2cOf:%d T2dOf:%d \n",
__func__, __LINE__, sizeof(struct Test2),
alignof(Test2::T2a), alignof(Test2::T2b),
alignof(Test2::T2c), alignof(Test2::T2d));
}
$ ./demo
[main,35] size:64 T1aOf:1 T1bOf:1 T1cOf:1 T1dOf:1
[main,40] size:22 T2aOf:1 T2bOf:1 T2cOf:1 T2dOf:1
这个没有见过使用的,只是看网上说有,没有深究,有了解的留言分享下,这里先谢谢了