打印
[资源分享]

C语言结构体对齐

[复制链接]
92|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
renzheshengui|  楼主 | 2023-12-21 09:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.对齐的概念

对齐是指将数据(数据成员,结构体)存放在合适的内存地址上,以使CPU访问数据效率最大化。简单讲,数据只能存储在地址是数据大小整数倍的内存地址上。这里的数据可以是基本数据类型(char,int,short,float,double),也可以是复合数据类型(struct)。

比如,int a;变量a需要存储在能够被4(这里假设int为4个字节)整除的内存地址上,这样CPU在访问内存时只需访问一次即可。对于结构体也不例外,只是结构体包含多个数据项,要稍微复杂些。

注:

1)计算机中的内存地址是按字节进行编址的。

2)对齐是针对内存地址对齐。

2.对齐值

1)数据成员的对齐值:char型为1字节,short型为2字节,int/float型为4字节,double型为8字节。
2)结构体的对齐值:其成员中对齐值最大的那个值。结构体的对齐值主要考虑到存在结构体数组的情况(访问效率)。
3)指定对齐值:用#pragma pack(n)时的指定对齐值。
4)数据成员、结构体的有效对齐值:自身对齐值和指定对齐值中较小者,即有效对齐值=min(自身对齐值,指定对齐值)。

对于4),举个例子:
#pragma pack(4)
struct A
{
    char a;
    short b;
    char c;
};
#pragma pack(0)

sizeof(struct A)=6

这里,并不是按4字节对齐,而是按自身对齐值进行对齐。char a按1(并没有按4,以下类同)字节对齐,short b按2字节对齐,因此,char a和short b之间需填充1个字节,char c按1字节对齐,这里已经有5个字节了,struct A按2字节对齐,char c后需填充1个字节,这样就是6个字节了。

同理,

#pragma pack(2)
struct A
{
    char a;
    float b;
    char c;
};
#pragma pack(0)

sizeof(struct A)=8

这里,就是按指定2字节对齐。不具体分析了。

3.对齐规则

1)结构体变量的首地址能够被其最宽基本类型成员的大小所整除。
2)结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal padding)。
3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

例(int占4字节):

struct A
{
    char a;
    int b;
    char c;
};

sizeof(struct A)=12

先分析结构体成员,char a按1字节对齐,占1字节,int b按4字节对齐,占4字节,char a,int b之间填充3个字节,char c按1字节对齐,共计9字节,再考虑结构体本身,struct A对齐值为int b的对齐值,按4字节对齐,char c后补充3字节。共计12字节。

3.指定对齐语法

1)语法1

#pragma pack(n)


#pragma pack(0)  //恢复默认对齐值

2)语法2

#pragma pack(push)  //保存原对齐值
#pragma pack(n)

#pragma pack(pop)  //恢复原对齐值

语法2适合存在嵌套使用的情况。
————————————————
版权声明:本文为CSDN博主「propor」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/propor/article/details/131721643

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

3858

帖子

2

粉丝