之前不清楚iOS是32位还是64位的时候,看见sizeof(int) 打印出来的结果是4的时候,就单纯地以为是32位的系统,即便是看到Mac的“关于本机”里的内存大小清清楚楚地写着是16G(64位OS内存一般为16G,即2的64次方),我也天真地以为大概macOS 和iOS 两者位宽大概不一样吧。因为楼主以前学Linux的,我清清楚楚地记得老师说:int 整型 的“整”体现在它与CPU本身的位宽一样。那iOS是基于Unix,Linux又是高仿的Unix,我就以为一样啊....所以是一直都是这么测的啊,直到,脑抽直接把指针传给sizeof,打印出来是8,
char *p = NULL; printf("------- sizeof(p) = %ld ----\n", sizeof(p)); 打印结果: ------- sizeof(p) = 8 ----
8字节,那为什么int只有4字节?凌乱....
然后在网上好一顿搜索,确实也找到了一些资料:(来自iOS32位和64位的坑 这篇文章挺好)
对于iOS设备来说
32位编译器
char :1个字节 char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器) short int : 2个字节 int: 4个字节 unsigned int : 4个字节 float: 4个字节 double: 8个字节 long: 4个字节,最大是2147483648,再大则溢出 long long: 8个字节 unsigned long: 4个字节
64位编译器
char :1个字节 char*(即指针变量): 8个字节 short int : 2个字节 int: 4个字节 unsigned int : 4个字节 float: 4个字节 double: 8个字节 long: 8个字节,最大是18446744073709552000 long long: 8个字节 unsigned long: 8个字节
比较得知,32与64区别主要在long,64位比32位大得多。 (这部分都是粘贴自iOS32位和64位的坑 这篇文章)
那现在已经明白了,目前在用的是64位系统,跟Linux毕竟还是不一样,不纠结这个问题了,继续下一个。
前面既然已经说了是64位,可是新疑问又来了
typedef struct my_Header { char msgHead[4]; short tag; int length; }My_Header; My_Header myHeader; memset(&myHeader, 0, sizeof(myHeader)); printf("------- head len = %d ----\n", sizeof(myHeader)); 按照结构体的对齐访问,OS的位宽又是8字节,所以猜测打印出来的结果应该是16字节,... 但是实际打印的是12字节, 这又是怎么肥事?要不是找到了上面的那篇资料,我真的又要以为iOS是32位的了,网上搜了好多,基本也是讲32位下的4字节对齐访问方式。 既然说到结构体的对齐访问,不如一起来复习一下,(以下内容都是基于Linux的32位平台下的,iOS平台下的内容有待考究,不过可以参考)
综上,1. 速度降低了2/3,所以效率低。
2. 对齐访问是牺牲了内存空间,换取了速度。
现在再来看看 sizeof(myHeader) 值为 12这事,还是觉得像4字节对齐。 不如再给myHeader加一个类型为long的成员: typedef struct my_Header { char msgHead[4]; short tag; int length; long test; }My_Header; My_Header myHeader;long为8字节,按照上面所讲,如果结构体是4字节对齐: (图误,应该和下一张图是一样的) 应该得出结构体所占大小为20字节; 如果是8字节对齐,则: 结构体所占大小为24字节 既然之前sizeof(myHeader) 值为 12,暂时认为是4字节对齐吧,那么按照刚才的分析,结构体所占大小应该为20字节 我们来实际运行看一看 …… ------- head len = 24 ---- 这下怎么圆回来?前面已经说了那么多 这要怎么理解?此处暂时存疑吧…… 我已经尽我最大努力画图了,看不看得懂全凭缘分了。 不过4字节对齐,8毕竟也是它的倍数,按刚刚的思路,仿佛是不影响…也没有找到什么确切的文章,只能理解成它是默认按4字节对齐的吧。…… ======================= 8月3日,更新 ======================= 其实刚刚最后一张图画完,就已经有点思路了,倒数第二张画的图有误,因为之前说了是在64位的条件下,所以画成4字节的位宽是不对的。 重新更正为: 如果结构体是4字节对齐,情况和下面一张图是一样的。 同理, typedef struct my_Header { char msgHead[4]; short tag; int length; }My_Header;结构体大小为12也可以被理解: 如果真的是8字节对齐访问的话,大小应该为8的倍数,所以可以判断OS并不是按8字节对齐的。 想要验证也很简单,用上面刚刚说的#prama pack(8)测试一下,可以得到结果为16 。
总结:
iOS情况下,是位宽为8字节,结构体对齐方式为按4字节对齐。