BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #44898同步于 2010/10/17
CPP机器人发帖

[合集] 再开一楼,sizeof()

shenlei
2010/10/17镜像同步0 回复
☆─────────────────────────────────────☆ feel48 (feel) 于 (Sat May 31 21:28:28 2008) 提到: struct Planet { char Name[10]; long Population; double Gravity; }; struct Planet { long Population; double Gravity; char Name[10]; }; sizeof(Planet) 为什么前面一个是24 后面一个是32 10+4+8 =22 补齐24 4+8+10 为什么补齐成了32? struct Planet { double Gravity; long Population; char Name[10]; }; 这个也是24 不明白了。 ☆─────────────────────────────────────☆ PtwCJ (鲜的每日C|头像不是我,我是长毛贼~~) 于 (Sat May 31 22:01:47 2008) 提到: 后面写的没看 第一个是10+2(补齐)+4+8=24 第二个是4+4(补齐)+8+10+6(补齐)=32 第三个是8+4+10+2(补齐)=24 【 在 feel48 的大作中提到: 】 : struct Planet : { : char Name[10]; : ................... ☆─────────────────────────────────────☆ mayao11 (卡马克的fans) 于 (Sat May 31 22:02:47 2008) 提到: 这个东西可以用一个宏来影响的 #pragma pack(n) n取的值对编译具体的行为有影响,具体的不能简单说明,反正1就表示紧凑不补位啦~~ 编译器怎么高兴就怎么做,这里面可能有内在的原因。不过要是我也不会在意的。 ☆─────────────────────────────────────☆ PtwCJ (鲜的每日C|头像不是我,我是长毛贼~~) 于 (Sat May 31 22:05:12 2008) 提到: 补齐按顺序来的 比如第二个 long占4位,然后接着来得是double,那么double之前的空间一定要是自己size的倍数,所以要补上4位在放置double 然后10个char 最后总和要保证是最大size元素的整倍数,故再补上6达到32 ☆─────────────────────────────────────☆ diy0829 (小纸条军团〓FreeThrow~DeVildIy) 于 (Sat May 31 22:22:22 2008) 提到: 跟奇偶地址有关的吧 ☆─────────────────────────────────────☆ ATV (ATV) 于 (Sat May 31 23:21:16 2008) 提到: 用G++没问题的,都是24 ☆─────────────────────────────────────☆ zhaotong (hotter) 于 (Sun Jun 1 11:32:00 2008) 提到: 恩,老问题了。 编译器有关,默认情况下gcc下都是24(为了尽量不浪费空间,32位机上最多补齐成4位。) [root@hotter test]# ./test 24 24 24 在文件头加上:#pragma pack(1),或 #pragma pack(2)后,结果: [root@hotter test]# ./test 22 22 22 修改成#pragma pack(4),或 #pragma pack(8)后,全部是24,猜测这是gcc编译器默认设置。 ☆─────────────────────────────────────☆ UnitTest (TDD) 于 (Sun Jun 1 21:22:31 2008) 提到: 【 在 ATV 的大作中提到: 】 : LZ是用VS2005 / VC6来编译的吧?赶紧扔掉。 。。。。这是冷笑话吗。。。。 其实这个问题和操作系统也有一定的关系,在linux下是本着节约空间的原则出发,所以在32位机下一般是按照4的倍数来对齐。而在Windows下是本着迁移性好的原则出发,即从16位机器迁移到32位机器,或者32位机迁移到64位机器的时候对齐原则不用作大改动,所以它的要求是任何k字节的基本类型的地址都必须是k的倍数。所以你可以发现Dev-C++出来的也是32,当然可能有些编译器提供了一些选项来让你控制对齐的策略。 ☆─────────────────────────────────────☆ hokkien (我脱,我脱,我脱脱脱!) 于 (Mon Jun 2 10:10:01 2008) 提到: 其实LZ这个问题意义也不大,对齐这种东西有时候是可有可无的,虽然有些系统下没有对齐可能产生异常,但大多数情况下,操作系统允许不对齐的发生。而且,这也跟不同编译器的实现有直接关系。VC默认对齐8字节 ☆─────────────────────────────────────☆ evengine (北邮人) 于 (Mon Jun 2 11:22:34 2008) 提到: 【 在 PtwCJ 的大作中提到: 】 : 补齐按顺序来的 : 比如第二个 : long占4位,然后接着来得是double,那么double之前的空间一定要是自己size的倍数,所以要补上4位在放置double : ................... 问下这位兄弟 32位系统,char [10] 补足4的整数倍是为了性能 那么为什么double之前的long要补足8的整数倍呢?感觉和性能无关的,难道是惯例? ☆─────────────────────────────────────☆ lazy (~杜~) 于 (Mon Jun 2 11:29:32 2008) 提到: 【 在 evengine 的大作中提到: 】 : 问下这位兄弟 : 32位系统,char [10] 补足4的整数倍是为了性能 : 那么为什么double之前的long要补足8的整数倍呢?感觉和性能无关的,难道是惯例? 因为double占8个字节,它的偏移量必须是8的倍数,而long只有4个字节,doouble本来的偏移量只有4,所以为了满足8的倍数这一要求,long要补4个。 ☆─────────────────────────────────────☆ evengine (北邮人) 于 (Mon Jun 2 12:03:00 2008) 提到: 【 在 lazy 的大作中提到: 】 : 因为double占8个字节,它的偏移量必须是8的倍数,而long只有4个字节,doouble本来的偏移量只有4,所以为了满足8的倍数这一要求,long要补4个。 其实我问的就是这个 为什么double的偏移量要是8的倍数 ☆─────────────────────────────────────☆ UnitTest (TDD) 于 (Mon Jun 2 12:07:19 2008) 提到: 【 在 evengine 的大作中提到: 】 : 其实我问的就是这个 : 为什么double的偏移量要是8的倍数 在Windows下,对齐要求是任何k字节的基本类型的地址都必须是k的倍数,见10楼 ☆─────────────────────────────────────☆ evengine (北邮人) 于 (Mon Jun 2 12:28:12 2008) 提到: 【 在 UnitTest 的大作中提到: 】 : 在Windows下,对齐要求是任何k字节的基本类型的地址都必须是k的倍数,见10楼 这样说起来就明白了 ☆─────────────────────────────────────☆ PtwCJ (鲜的每日C|头像不是我,我是长毛贼~~) 于 (Mon Jun 2 12:29:58 2008) 提到: 对齐一般是出于对性能的考虑,因为计算机读内存的时候都是按自己的字长读的,比如32位机器,一次(一个时钟周期)就读4byte的数据,所以每次读取都是从4byte的整数倍开始读 如果你的数据没有对齐,那么就会造成一些数据跨越了机器字长单位,这种情况下有的CPU要分两次读(所以慢了),有的CPU会产生异常,有的CPU会产生并为你捕捉异常,有的则自己帮你对齐 上面讲的都是理论上的东西,实际处理时不同的厂商有不同的策略,而且ms现在的CPU读取技术有了新发展,已经不太受这方面的限制了。 很早以前在CSDN上看见有很多人讨论这个,个人认为如果不搞硬件,这些东西没必要扣的太死,呵呵。知道怎么算就行了 【 在 evengine 的大作中提到: 】 : 问下这位兄弟 : 32位系统,char [10] 补足4的整数倍是为了性能 : 那么为什么double之前的long要补足8的整数倍呢?感觉和性能无关的,难道是惯例? ☆─────────────────────────────────────☆ PtwCJ (鲜的每日C|头像不是我,我是长毛贼~~) 于 (Mon Jun 2 12:34:24 2008) 提到: 还有,根据这个说gcc好的是无稽之谈,gcc和vc的结果不同完全是因为操作系统不同,这个前面已经有人说了 gcc编译的时候如果加上-malign-double,double类型就按8位对齐了(深入理解计算机系统讲的) ☆─────────────────────────────────────☆ ATV (ATV) 于 (Mon Jun 2 13:53:49 2008) 提到: 切~~~ 《程序员面试宝典》里就说,如果结构体里有比机器字节长度还大的,就按机器的。 double是应该被忽略的。 ☆─────────────────────────────────────☆ UnitTest (TDD) 于 (Mon Jun 2 14:09:13 2008) 提到: 【 在 ATV 的大作中提到: 】 : 切~~~ : 《程序员面试宝典》里就说,如果结构体里有比机器字节长度还大的,就按机器的。 : double是应该被忽略的。 咳咳,如果要给《程序员面试宝典》写个勘误表的话,那肯定不止十页..... ☆─────────────────────────────────────☆ PtwCJ (鲜的每日C|头像不是我,我是长毛贼~~) 于 (Mon Jun 2 14:50:43 2008) 提到: 咱们就是讨论,干嘛这么激动..... 也许你说的不错,但你可以找个权威一点的文献来佐证你的观点 鉴于你的这种态度,那多说无益了 【 在 ATV 的大作中提到: 】 : 切~~~ : 《程序员面试宝典》里就说,如果结构体里有比机器字节长度还大的,就按机器的。 : double是应该被忽略的。 ☆─────────────────────────────────────☆ PtwCJ (鲜的每日C|头像不是我,我是长毛贼~~) 于 (Mon Jun 2 14:54:46 2008) 提到: 这本书我也买了,看的云里雾里,唉 不过出于见识题目风格的角度,还是有一些价值的 【 在 UnitTest 的大作中提到: 】 : 咳咳,如果要给《程序员面试宝典》写个勘误表的话,那肯定不止十页..... ☆─────────────────────────────────────☆ zhaotong (hotter) 于 (Mon Jun 2 18:45:44 2008) 提到: 恩,前段时间看《程序员面试宝典》: sizeof(string) = 4 呃,这东西也能拿出来考? 库函数都不一样,linux下是 4 ,windows下是16.。。 ☆─────────────────────────────────────☆ Guilt (Guilt) 于 (Mon Jun 2 23:21:42 2008) 提到: 结构的对齐方式与内部成员定义的顺序有关的,一般来讲最好将成员函数按照从占用空间比较长的类型到比较短的类型的顺序来定义,编译时将会自动按照第一个定义的类型的长度来对齐,后面自然就对齐了 印象中是这样的。。有错请指正。。。
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。