32位机器 #pragma pack(4) short d; struct a{short a;short b;short c;} ; sizeof(a)==6 //为什么不为8

即使只占6个字节,它的下一个类型short d,同样要从%4==0的地址才能开始存储,
为什么不直接为8呢?

sizeof(a)只是说a的size,跟short d没有关系。
关于#pragma pack()和sizeof的用法和效果,有几条规则
1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2. 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员之后加上填充字节(trailing padding)。
如果定义了#pragma pack(n),则第二条规则里面,offset是该成员大小和n之间较小的数的整数倍。
所以你定义#pragma pack(4)的话,对于short类型没有区别,仍然可以紧密排列,sizeof(a)=3*2=6。追问

谢谢 不知道是不是第2、3条规则没理解好 (不知道它这样设计的原因)
按照这个规则 的确 是 sizeof(a)=3*2=6;但是紧接它后面的类型的存储地址还是要从%4==0的地方开始(32位机器),为何不直接让sizeof(a)=3*2+2(填充2个字节)=8,占八个字节 ,这样也可减少下一个类型存储首地址的计算操作啊
比如说:
32为平台
#pragma pack(4) //这个默认值也该是4
对于结构体总长度4的,按8对齐

追答

后面的数据类型跟a的size没有关系,就算是double需要%8那也不算在a的size里。a的结尾padding遵循规则3。
结构体的总长度应该是最宽基本类型成员大小的整数倍,如果最宽的小于4,那就没关系;如果最宽的大于4,按4对齐。
你可以试试这个:
#include
using namespace std;
#pragma pack(4)
struct as{
double d1;
char c1;
};
int main()
{
cout << sizeof(as) << endl;
return 0;
}
结果是12,因为double占8个,char占1个,pack(4)之后按4对齐。最后就是8+1+(3)=12.

追问

struct m {short a;short b;short c;}
为6 ,为什么不设计为按4字节对齐呢 ? 内存堆栈里,它占据的6字节后面还是要隔2个字节才开始新的存储(因为32位的,%4==0最快) ,再按照规则3,sizeof()偏偏只弄成6,不直接弄成8,隔那2个字节,不填充,也没法用(不用),所以不知道这样设计的原因。
希望高手继续给予指点 。。。。。。。谢谢

参考资料:http://blog.csdn.net/nellson/article/details/5293588

温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-09-22
属于字节对齐问题。请参考如下文档。

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网