代码之家  ›  专栏  ›  技术社区  ›  benzado

在iPhone OS 3.0上发布CGIMAGE时出现malloc错误的原因是什么?

  •  1
  • benzado  · 技术社区  · 15 年前

    我在开发iPhoneOS3.0SDK时发现了一个错误。基本上,如果我从位图图像上下文创建一个CGIMAGE,当我释放它时会得到以下错误:

    malloc: *** error for object 0x1045000: pointer being freed was not allocated
    *** set a breakpoint in malloc_error_break to debug
    

    相关代码如下:

    CGSize size = CGSizeMake(100, 100);
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    size_t bitsPerComponent = 8;
    size_t bytesPerPixel = 4;
    size_t bytesPerRow = size.width * bytesPerPixel;
    void *bitmapData = calloc(size.height, bytesPerRow);
    CGContextRef ctxt = CGBitmapContextCreate(bitmapData, size.width, size.height, bitsPerComponent, bytesPerRow, cs, kCGImageAlphaPremultipliedLast);
    // we could draw something here, but why complicate things?
    CGImageRef image = CGBitmapContextCreateImage(ctxt);
    CGContextRelease(ctxt);
    free(bitmapData);
    CGColorSpaceRelease(cs);
    CGImageRelease(image); // This triggers the error message.
    

    上面的示例是独立的,很明显没有违反任何保留/发布规则。我在iPhone模拟器3.0、3.1和3.1.2下测试了这段代码。该问题仅在3.0以下出现;3.1及更高版本中似乎已解决。 我还没有确认设备上的错误。

    1 回复  |  直到 14 年前
        1
  •  1
  •   benzado    14 年前

    问题指针似乎是图像的数据提供程序。如果在释放图像之前插入此行:

    CFRetain(CGImageGetDataProvider(image));
    

    那么3点0分一切都好。但是,如果该应用程序运行在更高版本的操作系统上,数据提供者将被泄露。因此,您必须检查操作系统版本,或者忽略它(malloc会记录一条错误消息,但不会抛出异常或以任何方式中断应用程序)。我一直在使用以下宏:

    #if TARGET_IPHONE_SIMULATOR
    // 3.0 CFVersion 478.470000
    // 3.1 CFVersion 478.520000
    #define BugFixRetainImageDataProvider(img) \
        if (kCFCoreFoundationVersionNumber == 478.47) { \
            CGDataProviderRef dp = CGImageGetDataProvider(img); \
            if (dp) CFRetain(dp); \
        }
    #else
    #define BugFixRetainImageDataProvider(img)
    #endif
    

    因为我不能在设备上复制它(我没有运行3.0的设备),所以我只在模拟器上应用这个修复程序。