字节对齐导致的iOS EXC_ARM_DA_ALIGN崩溃
本文原链接: http://www.cnblogs.com/zouzf/p/4455167.html
先看一下这个链接:http://www.cnblogs.com/ren54/archive/2013/01/11/2856207.html
我遇到情况和这位朋友很类似:用二进制方式从文件读取内容到内存,假设内容只有7个字节,前面三个字节是三个字符,后四个字节的内容是一个int数据,在把后四个字节转成int数据时如(pFileContent是char*指针,已指向第四个字节):int intValue = *(pFileContent); 就会崩溃报EXC_ARM_DA_ALIGN错误。
查了一下资料:http://www.justinyan.me/post/1609 、http://www.shaoqun.com/a/54537.aspx 、http://blog.csdn.net/slay_cn/article/details/6221637 ,是因为字节对齐问题引起的,大概描述如下(摘自前面三篇资料):
- 内存地址空间以byte划分,所以理论上访问内存地址可以从任意byte开始,但是事实上我们不是直接访问硬件地址,而是通过操作系统的虚拟内存地址来访问,虚拟内存地址是以字为单位的。一个32位机器的字长就是32位,所以32位机器一次访问内存大小就是4个byte。再者为了性能考虑,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
- 这个问题常见于对字节流进行处理解析,比如从网络收到一个数据包,读入本地缓存后进行处理,头两个字节是一个short标志,接下来四个字节是一个int参数,所以将指向这个位置的指针直接cast成int*来读取数据——于是问题就出现了,当读int*时,ARM要求字节对齐,而此时不对齐。则有可能出现EXC_ARM_DA_ALIGN异常而崩溃。
大概就是说,在进行强制数据类型转换的时候,(release版本)会要求内存字节对齐。编译release版本,编译器会对代码进行优化,在处理数据时要求数据结构在自然边界上对齐以提高CPU效率。
解决方法了http://www.shaoqun.com/a/54537.aspx:
方案1、在指针定义时加上编译器指令PACKED,则编译器在遇到此关键字时就不再要求字节对齐,而是自行进行正确的处理。
方案2、使用memcpy逐字节拷贝来绕过直接的int*指针读取。给memcpy传入参数时,先将参数转成void*类型,因为release的memcpy被优化掉了,在优化的版本中,将指针转成long型,4个4个字节的进行复制,于是又出现了字节对齐的问题。
我采用了方案2,给memcpy传参数时转成 void* 。
后记
当读取文件获取数据时经常会采用反序列化的方式来提高效率,如上篇文章提到的骨骼动画的优化,这个时候要特别注意字节对齐的问题,特别是现在做手游基本都会涉及到多平台,在定义一些struct时最好显示调用
#pragma pack(n)来指定字节对齐。windows下编译器默认是8字节对齐的,mac、iOS、Android(如果有误请指正)默认是4字节对齐的,而经常发生的时,在windows下对文件资源进行序列化,然后在iOS和Android上运行的时候读取文件进行反序列化,如果有个结构体如 struct myTest { char[5] name; int age; };就出问题了,windows下写进文件需要16个字节,而ARM设备下读取文件反序列化需要12个字节~~
上面说到:windows下默认是8字节对齐的,mac、iOS、Android(如果有误请指正)默认是4字节对齐的 ,这个说法是不严谨的,应该更多的是跟编译器有关吧,而编译器会根据系统和CPU特性来决定的吧,这块了解得不多,有了解的朋友可以留下链接和看法,谢了。
另外还有个疑惑,那个EXC_ARM_DA_ALIGN 崩溃会出现在Xcode5.1.1 出的release版本,而Xcode5.0.1 出的release版本却没事,一个小版本的有必要差异那么大么。。。。
本文原链接: http://www.cnblogs.com/zouzf/p/4455167.html
字节对齐导致的iOS EXC_ARM_DA_ALIGN崩溃的更多相关文章
- C语言字节对齐问题详解
引言 考虑下面的结构体定义: typedef struct{ char c1; short s; char c2; int i; }T_FOO; 假设这个结构体的成员在内存中是紧凑排列的,且c1的起始 ...
- C语言字节对齐问题详解(对齐、字节序、网络序等)
首先说明一下,本文是转载自: http://www.cnblogs.com/clover-toeic/p/3853132.html 博客园用的少,不知道怎么发布转载文章,只能暂时这样了. 引言 考虑下 ...
- C语言字节对齐问题详解【转】
引言 转自:http://www.cnblogs.com/clover-toeic/p/3853132.html 考虑下面的结构体定义: 1 typedef struct{ 2 char c1; 3 ...
- [转]C语言字节对齐问题详解
C语言字节对齐问题详解 转载:https://www.cnblogs.com/clover-toeic/p/3853132.html 引言 考虑下面的结构体定义: typedef struct{ ch ...
- arm的字节对齐问题总结(转)
问题由来:pc的lsb总是0,因为代码至少要字对齐.cm3的指令至少是半字对齐的(16) 一.啥是字对齐?为啥要字对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访 ...
- 关于C语言中结构体中的结构体成员导致的字节对齐问题
关于结构体的字节对齐是什么,就不赘述,再此附上一篇文章,介绍字节对齐:http://www.linuxsong.org/2010/09/c-byte-alignment/ 这里的结构体字节对齐的数据类 ...
- iOS之内存管理-字节对齐
字节对齐 1 struct Mystruct1{ 2 char a; //1字节 3 double b; //8字节 4 int c; //4字节 5 short d; //2字节 6 }Mystru ...
- ACE的CDR中的字节对齐问题
大家应该都知道计算机中间都有字节对齐问题.CPU访问内存的时候,如果从特定的地址开始访问一般可以加快速度,比如在32位机器上,如果一个32位的整数被放在能被32模除等于0的地址上,只需要访问一次,而如 ...
- ARM字节对齐问题详解
一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这 ...
随机推荐
- Linux更改主机名的最简单方法
之前写过一篇关于CentOS更改主机名的随笔,搞得很复杂,详见修改阿里云CentOS Linux服务器的主机名. 今天在askubuntu上发现一个很简单的方法(How do I change the ...
- Linux WAS7 启动异常
启动server1异常,信息如下: [root@cmiecmceprd02 bin]# ./startServer.sh server1ADMU0116I: Tool information is b ...
- Linux:常用快捷键
按键 作用 Ctrl+d 键盘输入结束或退出终端 Ctrl+s 暂定当前程序,暂停后按下任意键恢复运行 Ctrl+z 将当前程序放到后台运行,恢复到前台为命令fg Ctrl+a 将光标移至输入行头,相 ...
- 如何带领一个Android开发团队
1)重构,夜未眠 将框架从业务中剥离 如何提高开发效率 如何提高程序性能 单元测试 技术调研 代码版本管理 2)渠道包管理 自动打包工具 批量打渠道包的两种解决方案 定制渠道包的流程管理 3)稳定性, ...
- jquery的height()和javascript的height总结,js获取屏幕高度
jquery的height()和javascript的height总结,js获取屏幕高度 2014年9月18日 15048次浏览 引子 今天是九一八事变八十三周年,大家勿忘国耻!加油学习!经济和技术等 ...
- 微信小程序笔记(二)
微信小程序环境搭建与开发工具介绍 2-1 开篇介绍及下载工具 1.开发工具下载地址: http://t.cn/RVKH0HS 2.下载安装对应版本:win32,win64,mac; 2-2 小程序 ...
- Proxy模式:管理第三方API
软件中的Barrier. 数据从程序移到DB中时,要跨越数据库的Barrier.消息从一个PC到另一个PC时,要跨越网络Barrier. 跨越可能是复杂的,很可能处理Barrier的Code会多于处理 ...
- EndPoint详解
EndPoint详解 EndPoint主要用于暴露一些SpringMvc内部运行的信息,通常是通过SpringMvc的请求地址获取相关信息.如/health获取健康检查信息. 简单单元测试 @Test ...
- Spring之事件发布系统
springboot应用,启动spring容器大致有如下几个过程: 容器开始启动 初始化环境变量 初始化上下文 加载上下文 完成 对应的Spring应用的启动器的监听器可以监听以上的过程,接口如下: ...
- hdu 1284完全背包
http://acm.hdu.edu.cn/showproblem.php?pid=1284 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的 ...