Objective-C字符数组初始化导致访问属性时触发EXC_BAD_ACCESS错误
问题根源:栈溢出导致的EXC_BAD_ACCESS
你的错误完全是栈内存溢出引发的,和MyFile对象或者NSFileHandle本身无关——你在栈上分配了远超栈容量的数组,直接破坏了栈的结构,导致后续访问栈上变量时出现野指针。
栈分配 vs 堆分配的核心区别
char buffer[N];是栈上分配:栈是线程专属的小内存区域(iOS/macOS默认栈大小一般在8MB左右),用来存储局部变量、函数调用的返回地址和上下文。栈空间非常有限,一旦分配超大数组,会直接耗尽栈空间,覆盖栈上的其他关键数据(比如你的file指针、函数返回地址)。char *buffer = malloc(N);是堆上分配:堆是全局的大内存池,专门用来处理大块内存分配,只要系统剩余内存足够就能成功,不会影响栈的结构。
逐个分析你的函数行为
- readFile1(正常):用
malloc在堆上分配2亿字节,堆能容纳这么大的内存,栈结构没被破坏,所以所有操作正常。 - readFile2(崩溃):直接在栈上声明
char buffer[200000000];,2亿字节远超过栈的容量,栈瞬间溢出,栈上的file指针被覆盖成无效地址,执行[file handle]时就触发了EXC_BAD_ACCESS。 - readFile3(正常):栈上只分配10字节,远小于栈的剩余空间,栈结构完好,所以操作正常。
- readFile4(崩溃):虽然把数组声明放在
@autoreleasepool里,但本质还是栈分配,2亿字节依然会撑爆栈,破坏栈上的变量或上下文,后续访问buffer时触发崩溃。
为什么之前正常突然出问题?
大概率是环境或代码的细微变化导致:
- 系统更新后栈大小被调整;
- 你的代码新增了其他栈上变量,挤占了栈空间;
- 之前
bufferSize的数值远小于2亿,最近调整后才触发溢出。
解决方案
- 所有需要大内存的缓冲区,一律用堆分配(
malloc/calloc/realloc),用完记得调用free(buffer)避免内存泄漏; - 如果一定要用栈数组,确保大小控制在几十KB以内,绝对不能超过栈的容量限制。
内容的提问来源于stack exchange,提问作者Foxyz
相关产品推荐
相关产品推荐

