2009-12-28 5 views
1

J'ai identifié un bug lors du développement de l'iPhone OS 3.0 SDK. En gros, si je crée un CGImage d'un contexte d'image bitmap, je reçois l'erreur suivante quand je le libérer:Source d'une erreur malloc lors de la sortie d'une CGImage sur iPhone OS 3.0?

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

Voici le code correspondant:

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'exemple ci-dessus est autonome et il est assez clair qu'aucune règle de conservation/libération n'est violée. J'ai testé ce code sur l'iPhone Simulator sous 3.0, 3.1 et 3.1.2. Le problème se produit uniquement sous 3.0; il semble avoir été corrigé en 3.1 et plus tard. Je n'ai pas confirmé le bug sur l'appareil.

Répondre

1

Le pointeur de problème semble être le fournisseur de données de l'image. Si j'insérer cette ligne avant de libérer l'image:

CFRetain(CGImageGetDataProvider(image)); 

tout va bien sur 3,0. Mais, si l'application est exécutée sur un système d'exploitation ultérieur, le fournisseur de données sera divulgué. Vous devez donc vérifier la version du système d'exploitation ou simplement l'ignorer (malloc consigne un message d'erreur mais ne déclenche pas d'exception ou n'interrompt pas l'application). J'utilise la macro suivante:

#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 

Puisque je ne peux pas le reproduire sur l'appareil (je n'ai aucun périphérique en cours d'exécution 3.0) J'applique ce correctif sur le simulateur seulement.

Questions connexes