程序设计中的字节填充

domustdo 2004-04-22 09:02:03
拙作一篇,请多指教!
win32中(使用编译器gcc3.2、bcc5.64、vc7.1):

struct st1 {
bool b;
};
sizeof(st1);应该是多少? 1

struct st2 {
bool b;
int i;
};
sizeof(st2);应该是多少? 是5? 8

struct st3 {
bool b;
short s;
};
sizeof(st3)是多少? 是3? 4

struct st4 {
bool b1;
short s;
int i;
int t;
};
sizeof(st)应该是多少呢? 11? 12

现在32位计算机上,聚集型的结构体大小会受到alignment的限制,为使其能有效的在内存中存取,通常编译器通常会安插一些byte填充,使得alignment调整到4的整数倍(win32中),以使bus运输量达到最高效率。

st4中b1和s可以安排到一个4bytes中,所以st4为12,既要满足上面的alignment的调整原则,也要保证尽可能小,同时要保证顺序性,即:
struct st5 {
bool b1;
int i;
short s;
int t;
};
此时由于i分开了b1和s,这时候两个要分别填充,所以sizeof(st5)为16

但是有一个地方,就是涉及到double的总是会多添加4个byte。
struct st6 {
int i;
double d;
};
sizeof(st6)不是12,而是16,这个地方就有点想不通了。12不已经是4的倍数了么,干吗还要加4bytes?

再来看看:
struct st7 {
int i;
double d;
bool b;
};
sizeof(st7)为24

struct st8 {
int i;
bool b;
double d;
};
sizeof(st8)为16

struct st9 {
short i;
int m;
short d;
struct {
short p;
double e;
bool b;
};
};
sizeof(st9)为40

那么到底编译器是按照什么方式来决定填充字节数的呢?
我想可能是这样的:编译器以struct中(包括其嵌套类型中的)最大的类型的长度为alignment标准(假设称为填充单位),对struct中的变量进行字节填充,从前往后如果相邻变量能够安排在一个填充单位中,就尽量安排在一个填充单位中,但如果有超出的部分,哪怕是一个byte,都会按照填充单元进行填充。比如上面的st8如果在bool b;后面添加一个int,则这个int就会被填充。当然这些都是编译器--机器相关的。通过打印struct中各个元素的偏移量就可以看出来,利用stddef.h中定义的offsetof(struct_type, member)来打印偏移量。

对于类也有类似的情况,至于其他比较复杂的情况,大家不妨试试看。如果您有什么高见,欢迎提出讨论,谢谢!
...全文
305 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
ToIP 2004-04-22
  • 打赏
  • 举报
回复
哦,是这样啊,学习
domustdo 2004-04-22
  • 打赏
  • 举报
回复
对,可以使用#pragma pack宏告知是否要进行alignment以及alignment的字节数。
#pragma pack(1) 将会消除填充字节
#pragma pack(push, st2, 2) 以2为标准对st2进行字节填充,这样上面的sizeof(st2)为10
ToIP 2004-04-22
  • 打赏
  • 举报
回复
可以告诉编译器不要填充
#pragma pack(push)/(pop)

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧