#pragma pack(1) 修改数据对齐导致NSValue 读取数据问题,x86_64,stack buffer overflow

5 阅读1分钟

开发时发现在x86_64的架构的mac上,有一个函数一执行就会崩溃

问题在于特殊数据存储到NSValue以及从NSValue读取该数据。

  1. 数据是struct类型,同时通过 #pragma pack(1) 改变了其对齐方式。(为了减少struct的内存占用)
#pragma pack(1)
struct saveData{
char name[3];
int age;
double weight;
}

按照4字节的话,saveData的内存大小是 4+4+8 = 16 。 而改为1字节后,就变为 3+4+8 = 15。

  1. NSValue保存struct类型数据时,需要通过类型。这里@encode 无法识别 #pragma pack(1),导致存储的数据大小是 16。而读取时就还是以 15来读取。
//存储
NSValue *value = [NSValue valueWithBytes:item objCType:@encode(saveData)];

//读取
saveData item = {0};
[value getValue:&item];

这就导致了 stack buffer overflow ,也就是栈溢出。此时app就可能闪退。

而ARM架构的就不一定,因为ARM对于栈溢出的情况更加宽松。

解决方案: 不要用nsvalue来保存数据,例如NSData