free()调用适用于模拟器,让iPad生气。 iPad粉碎

时间:2010-07-23 11:33:19

标签: iphone c objective-c memory-management free

我的应用内存不足。为了解决这个问题,我释放了一个将帧缓冲区写入图像的函数中使用的两个非常大的数组。该方法如下所示:

-(UIImage *) glToUIImage {
    NSInteger myDataLength = 768 * 1024 * 4;
    // allocate array and read pixels into it.
    GLubyte *buffer = (GLubyte *) malloc(myDataLength);
    glReadPixels(0, 0, 768, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    // gl renders "upside down" so swap top to bottom into new array.
    // there's gotta be a better way, but this works.
    GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
    for(int y = 0; y <1024; y++)
    {
            for(int x = 0; x <768 * 4; x++)
            {
                    buffer2[(1023 - y) * 768 * 4 + x] = buffer[y * 4 * 768 + x];
            }
    }

     // make data provider with data.
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL);

    // prep the ingredients
    int bitsPerComponent = 8;
    int bitsPerPixel = 32;
    int bytesPerRow = 4 * 768;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

    // make the cgimage
    CGImageRef imageRef = CGImageCreate(768, 1024, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

    // then make the uiimage from that
    UIImage *myImage = [UIImage imageWithCGImage:imageRef];

    //free(buffer);
    //free(buffer2);

    return myImage;
}

注意两个叫到free(缓冲区)和free(buffer2)到底有没有?这些在iPad模拟器上工作正常,消除了内存问题,让我产生了无礼。然而,他们立刻杀了iPad。就像第一次执行它一样。如果我删除free()调用它运行正常,一两分钟后就会耗尽内存。那么为什么free()调用会使设备崩溃?

注意 - 调用free()不是显式崩溃设备,而是在以后崩溃。但这似乎是根本原因/.../ p>

编辑 - 有人询问它究竟在哪里崩溃。此流程继续将图像返回到另一个对象,该对象将其写入文件。调用'UIImageJPEGRepresentation'方法时,它会生成EXT_BAD_ACCESS消息。我假设这是因为我传递它写入文件的UIImage是损坏的,null或其他东西。但这只有在我释放这两个缓冲区时才会发生。

我知道内存是否与UIIMage有某种关系,但它确实不应该,特别是因为它在模拟器上工作。我想知道iPad是如何处理“免费”通话的......

3 个答案:

答案 0 :(得分:8)

从阅读docs开始,我相信CGDataProviderCreateWithData只会引用 buffer2指向的内存,而不是复制它。您应该保留它,直到图像被释放。

试试这个:

static void _glToUIImageRelease (void *info, const void *data, size_t size) {
    free(data);
}

-(UIImage *) glToUIImage {
    NSInteger myDataLength = 768 * 1024 * 4;
    // allocate array and read pixels into it.
    GLubyte *buffer = (GLubyte *) malloc(myDataLength);
    glReadPixels(0, 0, 768, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    // gl renders "upside down" so swap top to bottom into new array.
    // there's gotta be a better way, but this works.
    GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
    for(int y = 0; y 

答案 1 :(得分:1)

首先,您应该检查malloc是否失败并返回NULL。但是,如果这不能解决您的问题,请使用调试器并逐步执行您的程序以查看其失败的确切位置(或至少获得堆栈跟踪)。根据我的经验,奇怪的失败,比如在未预料到的区域崩溃,几乎总是缓冲区溢出,在一段时间之前破坏了任意数据。

答案 2 :(得分:0)