繁体   English   中英

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

[英]free() call works on simulator, makes iPad angry. iPad smash

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

-(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()的调用,它明确地崩溃了设备,它会在以后崩溃。 但这似乎是根本原因/ ..

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

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

从阅读文档 ,我相信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

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

缓冲区尺寸过小? 看看循环。

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];
     }
}

令y == 0和x ==(768 * 4)-1,buffer2的索引超过分配的大小。 可能在之前的范围之外?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM