user-0 提问: 求struct union的大小

回复:
user: user-0
content: 问题还是没有解决……

user: user-1
content: typedef union  {     long i; 不小于4个字节     int k[5];不小于10个字节     char c;不小于1字节 }DATE; 应该是；不小于10个字节。   struct data {     int cat;不小于2个字节     DATE cow;不小于10个字节     double dog;这个很难确定，保守的说；不小于2个字节。 }too;这个，应该不少于14个字节。  c  基本类型长度是一个机器字，而机器字的长度是不统一的，与机器有关。c不保证类型长度，只是说“不少于某长度” 一个 int 的长度不小于，一个 short int长度。而一个short int不低于2个字节，所以，一个int也就不少于2个字节。 float double 没有说明具体的参考长度，可能是一个机器字。  c 没有对齐要求，对齐是目标机的要求，目标机的不同，对齐也就不同。

user: user-2
content: 引用 楼主 taotao945 的回复: typedef union  { 	long i; 	int k[5]; 	char c; }DATE;  struct data { 	int cat; 	DATE cow; 	double dog; }too;  求sizeof(struct data)+sizeof(max))是多少，为什么 struct data里面是怎么对齐的。。。   在4字节对齐下，你上面写的没涉及到对齐，因为都是齐的... typedef union  { 	long i; 	int k[5]; 	char c; }DATE;  4*5 = 20 struct data结构 4 + 20 + 8 = 32 想弄清楚对齐： struct A {    int a;    char b;    short c; }； struct B {    char b;    short c;    int a; }； 看看A和B的大小

user: user-3
content: #include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //

user: user-4
content: 依据环境的吧要？标准只规定了char是一个字节，其他基本类型没有明确规定大小吧。另外具体的系统是按多少字节分配一个空间也是根据系统来的吧。所以没有一个统一的答案吧，这是个按实现定义的问题吧。

user: user-5
content: 其实应该换一个角度来想，按哪种方式对齐，需要把所有成员数据都拆成内置类型，然后再看整数倍（不包括数组）。所以DATE其实可以认为是int k[5];组成的，撇开数组后类型是int，所有的成员都没有超过4字节，所以是按4字节对齐的。

user: user-5
content: 引用 11 楼 taotao945 的回复:[quote=引用 10 楼 max_min_ 的回复:] [quote=引用 9 楼 max_min_ 的回复:] [quote=引用 8 楼 taotao945 的回复:] [quote=引用 7 楼 max_min_ 的回复:] w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？[/quote] sizeof(struct data)+sizeof(max)  max是什么呢？ [/quote] 看到了 后面就是 4+ 20 +8 =32  [/quote] 亲，为什么不用补齐呢？结构体的大小不得是最宽基本类型的整数倍么？而且偏移量也得是成员大小的整数倍啊，都不满足呢？[/quote] 你想多了，这个规则其实指的是动态选择成按1、2、4、8、16字节方式对齐，对于20字节什么的是无效的，不然要浪费多少空间啊。

user: user-6
content: 引用 11 楼 taotao945 的回复:[quote=引用 10 楼 max_min_ 的回复:] [quote=引用 9 楼 max_min_ 的回复:] [quote=引用 8 楼 taotao945 的回复:] [quote=引用 7 楼 max_min_ 的回复:] w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？[/quote] sizeof(struct data)+sizeof(max)  max是什么呢？ [/quote] 看到了 后面就是 4+ 20 +8 =32  [/quote] 亲，为什么不用补齐呢？结构体的大小不得是最宽基本类型的整数倍么？而且偏移量也得是成员大小的整数倍啊，都不满足呢？[/quote] 32位都是4字节补齐就好了阿！你这里都是4字节对齐的啊！

user: user-0
content: 引用 10 楼 max_min_ 的回复:[quote=引用 9 楼 max_min_ 的回复:] [quote=引用 8 楼 taotao945 的回复:] [quote=引用 7 楼 max_min_ 的回复:] w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？[/quote] sizeof(struct data)+sizeof(max)  max是什么呢？ [/quote] 看到了 后面就是 4+ 20 +8 =32  [/quote] 亲，为什么不用补齐呢？结构体的大小不得是最宽基本类型的整数倍么？而且偏移量也得是成员大小的整数倍啊，都不满足呢？

user: user-6
content: 引用 9 楼 max_min_ 的回复:[quote=引用 8 楼 taotao945 的回复:] [quote=引用 7 楼 max_min_ 的回复:] w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？[/quote] sizeof(struct data)+sizeof(max)  max是什么呢？ [/quote] 看到了 后面就是 4+ 20 +8 =32

user: user-6
content: 引用 8 楼 taotao945 的回复:[quote=引用 7 楼 max_min_ 的回复:] w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？[/quote] sizeof(struct data)+sizeof(max)  max是什么呢？

user: user-0
content: 引用 7 楼 max_min_ 的回复:w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！  我敲了代码，运行结果是52，但是不懂，union的话大小是20这个明白，但后面一个怎么算都不是编译器的运行结果啊，可以指点下吗？

user: user-6
content: w网上很多这样的内存对齐的介绍的！看看理论知识！自己再敲下代码就明白了！

user: user-2
content: 1L都写出对齐怎么算

user: user-0
content: 引用 2 楼 yangw150 的回复:sizeof(struct data) = 24（4+10+8+2），最后的加2为了字节对齐，sizeof(max)是啥东西，没看到max 不好意思写漏了，掉了句 DATE max;

user: user-7
content: 这个对齐补齐的问题跟环境有关系。。。

user: user-5
content: 引用 2 楼 yangw150 的回复:sizeof(struct data) = 24（4+10+8+2），最后的加2为了字节对齐，sizeof(max)是啥东西，没看到max 算错了吧，Union Date是20，应该是 4+20+8=32吧，下面是我用VS打印出来的：class data      size(32):         +---  0      | cat  4      | DATE cow 24      | dog         +---

user: user-8
content: sizeof(struct data) = 24（4+10+8+2），最后的加2为了字节对齐，sizeof(max)是啥东西，没看到max

user: user-9
content: 关于字节对齐网上有很多讲解，这里贴一篇出来。http://blog.csdn.net/21aspnet/article/details/6729724 另外，以下是我个人的总结，楼主可以借鉴一下。 1. 在X86主机上，GNU和VC默认的对齐方式都为4字节对齐。 2. 对于基本类型，其地址如果在其类型大小倍数的地址上，则为自然对齐。对于数组，以其基本类型对齐；对于结构和联合，以最大的成员作为对齐方式。结构成员按照声明顺序在内存中存放。 3. 结构成员的大小必须是对齐方式的整数倍，结构成员需自然对齐。 4. 改变对齐的方式有： #pragma pack (n)设置n字节对齐 #pragma pack ()恢复默认的对齐方式 对于GNU还有在定义结构的最后加上__attribute__((aligned(n)))，n如果比结构对齐方式小，则无效，没有n使用默认；__attribute__((packed))取消编译过程中的对齐优化，按照实际字节排列。