龙空技术网

C语言结构体内存对齐方式

温柔ClarkH 800

前言:

当前小伙伴们对“c语言输出对齐”大约比较关切,同学们都需要剖析一些“c语言输出对齐”的相关资讯。那么小编同时在网络上汇集了一些关于“c语言输出对齐””的相关内容,希望你们能喜欢,朋友们一起来了解一下吧!

规则:

1、基本数据类型按自身类型大小对齐。

比如在64位平台下:

double和指针类型变量首地址是8的倍数;

int变量首地址是4的倍数;

short变量首地址是2的倍数;

bool和char没有特别要求。

2、结构体按成员中最大对齐值进行对齐。

比如

// sizeof(R) = 24// 按8字节对齐(按double对齐值对齐)struct R {    char m_ch; // 根据规则1,m_width的起始地址要是8的倍数,所以m_ch要占用8个字节    double m_width; // 根据规则1,char数组的对齐要求是1字节,所以double依然是占8个字节    char m_name[6]; // 根据规则3,结构体总大小要是double大小的倍数,所以再填充2个字节};// sizeof(T) = 32// 按8字节对齐(按R对齐值对齐)struct T {    int m_no; // R的起始地址要是8的倍数,所以m_no要再填充4个字节    R m_r;};// sizeof(T) = 40// 按8字节对齐struct U {    bool m_ok;  // T的起始地址要是8的倍数,所以m_ok要再填充7个字节    T m_t;};

3、结构体的总大小是成员中最大对齐值的倍数

为了满足各个成员的对齐要求,各个成员之间甚至对象的末尾都可能插入一定量的填充字节。

为什么有的对象会在末尾插入一定量的填充字节呢?

因为编译器在考虑一个类型的大小时,不仅要考虑一个对象的对齐要求,还要考虑该类型对象数组的对齐要求,这样才能保证用户在使用对象数组时也具有和单个对象一样的访问效率。

举例:

bool和unsigned char类型的对齐值是1,enum类型的对齐值是4,double的对齐值是8

所以a占用4个字节(1个实际字节 + 3个填充字节) 保证b的首地址是4的倍数。

b占用4个字节。

c占用8个字节(1个实际字节 + 7个填充字节) 保证d的首地址是8的倍数。

d占用8个字节。

e占用8个字节(1个实际字节 + 7个填充字节),根据规则3,结构体大小要是double大小的整数倍,所以填充7个字节,整个结构体大小为32字节。

标签: #c语言输出对齐 #结构体内存对齐算法 #c语言输出左对齐和右对齐怎么设置 #c语言结构体内存对齐原则