Domanda

Ho identificato un bug, mentre lo sviluppo contro il 3.0 SDK iPhone OS. In sostanza, se creo un CGImage da un contesto di immagini bitmap, ottengo il seguente errore quando ho comunicato che:

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

Ecco il codice in questione:

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.

L'esempio precedente è autosufficiente ed è abbastanza chiaro non mantengono / regole di rilascio sono stati violati. Ho provato questo codice su iPhone Simulator sotto 3.0, 3.1 e 3.1.2. Il problema si verifica solo in 3.0; sembra essere stato fissato in 3.1 e versioni successive. non ho confermato il bug sul dispositivo.

È stato utile?

Soluzione

Il puntatore problema sembra essere provider di dati dell'immagine. Se inserisco questa riga prima di rilasciare l'immagine:

CFRetain(CGImageGetDataProvider(image));

allora tutto va bene su 3.0. Ma, se l'applicazione è in esecuzione su un sistema operativo più tardi, il provider di dati sarà trapelato. Quindi, è necessario verificare la versione del sistema operativo o semplicemente ignorarlo (malloc registra un messaggio di errore, ma non un'eccezione o interrompere l'applicazione in alcun modo). Sto usando la seguente macro:

#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

Dal momento che non riesco a riprodurre sul dispositivo (non ho alcun dispositivo in esecuzione 3.0) Applico questa correzione sul simulatore unico.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top