1.首先说32位与64位的问题
之前不清楚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毕竟还是不一样,不纠结这个问题了,继续下一个。
2.其次是结构体对齐访问的问题
前面既然已经说了是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平台下的内容有待考究,不过可以参考)
结构体的对齐访问:
What:
struct header
{
char a;
int b;
};
struct header haed;
在这个结构体中,打印输出该结构体的字节,发现它占了8个字节。char a 本应是1字节,但实际在这个结构体中,占4字节,这就是“对齐访问”。
Why:为何要对齐访问
1.硬件限制
2.提高效率:
1)对齐访问:
如上图,此时的b,通过一次ldr指令,即可访问到
2)非对齐访问:
如下图
则读取b的步骤变成了:
1.读取这3个字节
2.读取这一个字节
3.结合
综上,1. 速度降低了2/3,所以效率低。
2. 对齐访问是牺牲了内存空间,换取了速度。
How:
#prama pack(n) // 开头。n = 1, 4, 8...
......
......
#prama pack() // 结尾
现在再来看看 sizeof(myHeader) 值为 12这事,还是觉得像4字节对齐。 不如再给myHeader加一个类型为long的成员:typedef struct my_Header { char msgHead[4]; short tag; int length; long test; }My_Header;
long为8字节,按照上面所讲,如果结构体是4字节对齐:My_Header myHeader;
(图误,应该和下一张图是一样的)
应该得出结构体所占大小为20字节;
如果是8字节对齐,则:
结构体所占大小为24字节
既然之前sizeof(myHeader) 值为 12,暂时认为是4字节对齐吧,那么按照刚才的分析,结构体所占大小应该为20字节
我们来实际运行看一看……------- head len = 24 ----
![]()
这下怎么圆回来?前面已经说了那么多这要怎么理解?此处暂时存疑吧……
其实刚刚最后一张图画完,就已经有点思路了,倒数第二张画的图有误,因为之前说了是在64位的条件下,所以画成4字节的位宽是不对的。重新更正为:
如果结构体是4字节对齐,情况和下面一张图是一样的。
同理,结构体大小为12也可以被理解:typedef struct my_Header { char msgHead[4]; short tag; int length; }My_Header;
如果真的是8字节对齐访问的话,大小应该为8的倍数,所以可以判断OS并不是按8字节对齐的。想要验证也很简单,用上面刚刚说的#prama pack(8)测试一下,可以得到结果为16 。
总结:
iOS情况下,是位宽为8字节,结构体对齐方式为按4字节对齐。