结构体大小问题

来源:本站
导读:目前正在解读《结构体大小问题》的相关信息,《结构体大小问题》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《结构体大小问题》的详细说明。
简介:本文介绍了计算的方法、对其方式等内容。

结构体(struct)的sizeof值,并不是简单的将其中各元素所占字节相加,而是要考虑到存储空间的字节对齐问题。先看下面定义的两个结构体.

struct

{

char a;

short b;

char c;

}S1;

struct

{

char a;

char b;

short c;

}S2;

分别用程序测试得出sizeof(S1)=6 , sizeof(S2)=4

可见,虽然两个结构体所含的元素相同,但因为其中存放的元素类型顺序不一样,所占字节也出现差异。这就是字节对齐原因。通过字节对齐,有助于加快计算机的取数速度,否则就得多花指令周期。

字节对齐原则

结构体默认的字节对齐一般满足三个准则:

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

2) 结构体每个成员相对于结构体首地址的偏移量(offset,即每个成员的起始地址)都是成员自身大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

注意:当结构体成员里面有数组成员时,如int a[10],要看成10个整形变量才参与计算。

通过这三个原则,就不难理解上面两个struct的差异了.

对于struct S1, 为了使short变量满足字节对其准则(2), 即其存储位置相对于结构体首地址的offset是自身大小(short占2个字节)的整数倍,必须在字节a后面填充一个字节以对齐;再由准则(3),为了 满足结构体总大小为short大小的整数倍,必须再在c后面填充一个字节。

对于struct S2, 却不必如上所述的填充字节,因为其直接顺序存储已经满足了对齐准则。

如果将上面两个结构体中的short都改为int(占4个字节), 那么会怎么样呢? 程序得出sizeof(S1)=12, sizeof(S2)=8

利用上面的准则,也不难计算得出这样的结果。S1中在a后面填充3个字节、在c后面填充3个字节,这样一共12个字节;S2中在a、b顺序存储之后填充两个字节用以对其,这样一共就8个字节。

当然,在某些时候也可以设置字节对齐方式。这就需要使用 #pragma pack 。

#pragma pack(push) //压栈保存

#pragma pack(1)// 设置1字节对齐

struct

{

char a;

short b;

char c;

}S1;

#pragma pack(pop) // 恢复先前设置

如上所示,将对其方式设为1字节对齐,那么S1就不填充字节,sizeof为各元素所占字节之和即4。这一点在从外部2进制文件中读入struct大小的数据到struct中,是很有用的.

另外,还有如下的一种方式:

· __attribute((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。

· __attribute__ ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。

提醒:《结构体大小问题》最后刷新时间 2024-03-14 01:03:47,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《结构体大小问题》该内容的真实性请自行鉴别。