程序设计中的字节填充
拙作一篇,请多指教!
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)来打印偏移量。
对于类也有类似的情况,至于其他比较复杂的情况,大家不妨试试看。如果您有什么高见,欢迎提出讨论,谢谢!