簡體   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