读取文件后,Objective-C与EXC_BAD_ACCESS崩溃

时间:2017-07-06 03:34:14

标签: ios objective-c

EXC_BAD_ACCESS导致我的应用崩溃。当您尝试访问单位化或取消分配的内存但我无法找到位置时,通常会发生此问题。我试图在Xcode中与Zombie核对但没有成功。应用程序崩溃和仪器没有注意到僵尸。 我正在使用ARC。

错误的访问发生在方法的末尾,在结束的花括号上。 (见截图)。该问题仅发生在发布模式(带优化),仅适用于少数设备。

enter image description here

为了测试,我做了一个虚拟项目,在didFinishLaunching之后立即调用该方法。

调用堆栈

  1. didFinishLaunchingWithOptions
  2. Alloc并初始化我的自定义对象
  3. 在新创建的对象上调用readFile
  4. 执行readFile中的代码
  5. 即将退出readFile,但应用崩溃
  6. 这是代码的简化版本

    - (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"];
    

1 个答案:

答案 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