EXC_BAD_ACCESS导致我的应用崩溃。当您尝试访问单位化或取消分配的内存但我无法找到位置时,通常会发生此问题。我试图在Xcode中与Zombie核对但没有成功。应用程序崩溃和仪器没有注意到僵尸。 我正在使用ARC。
错误的访问发生在方法的末尾,在结束的花括号上。 (见截图)。该问题仅发生在发布模式(带优化),仅适用于少数设备。
为了测试,我做了一个虚拟项目,在didFinishLaunching之后立即调用该方法。
调用堆栈
这是代码的简化版本
- (void)readFromFile:(NSString *)fileName {
if (!fileName) {
return;
}
NSString* filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
if (!filePath) {
return;
}
FILE* file = fopen([filePath UTF8String], "r");
if (file == NULL) {
return;
}
size_t length;
char *cLine = fgetln(file, &length);
// I don't think it matters, but the file has about 400 000 lines
while (length > 0) {
char str[length - 1]; // All lines length are > 2
strncpy(str, cLine, length);
str[length - 1] = '\0'; // The crash would still occurs without this line, but less often
// Custom code with str
cLine = fgetln(file, &length);
}
fclose(file);
}
如果它可以帮到你,这里是我的读者对象的代码
@protocol MyReaderProtocol <NSObject>
- (void)readFromFile:(NSString *)fileName;
@end
@interface MyReader : NSObject <MyReaderProtocol>
@end
// How I initialize the objet in the app delegate
MyReader myReader = [[MyReader alloc] init];
[myReader readFromFile:@"myFile.txt"];
答案 0 :(得分:1)
仅基于阅读您的代码
对fgetln()
的函数调用会在length
中返回该行中的字符数。
带有 n 元素的C字符数组声明为char a[n]
,元素的地址为a[0]
到a[n-1]
。
你需要为EOS存储length
个字符加1,你分配的容量数组length - 1
太短了。
您的strncpy()
然后写入数组末尾。
最后,当最大索引为length - 1
时,您在索引length - 2
处编写EOS。
你只用1个字节覆盖(你在行的最后一个字符上写EOS),但这足以破坏堆栈上数组旁边的任何东西(可能是cLine
.. 。)
HTH