Elliott
Elliott

Reputation: 4628

CGLayerCreateWithContext CGContext leak

Why is this leak occurring?

I very much dislike the idea of asking a question that's very specific and unlikely to help very many other people but after hours of scratching my head I'm left with no option.

The leaks instrument reports that the following code has a leak:

- (void)likeABarrelFullOfHoles
{
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(50.0f, 50.0f), YES, 0.0f);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGLayerRef *shapeLayers = malloc(3 * sizeof(*shapeLayers));

    for (int i = 0; i < 3; i++)
    {
        // Leak culprit.
        shapeLayers[i] = CGLayerCreateWithContext(context, CGSizeMake(5.0f, 5.0f), NULL);
    }

    for (int i = 0; i < 3; i++) {
        free(shapeLayers[i]);
    }
    free(shapeLayers);

    UIGraphicsEndImageContext();
}

Specifically, it reports that the CGLayerCreateWithContext function is the problem but that it's leaking CGContext objects and not CGLayer objects, which it returns:

Leaks Leaks

I don't doubt that my problem is due to a fundamental lack of understanding of memory management/dynamic allocation and someone is going to wave their 'you should know this' finger at me because the following code appears to have no leaks:

- (void)noLeaks
{
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(50.0f, 50.0f), YES, 0.0f);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGLayerRef shapeLayer = CGLayerCreateWithContext(context, CGSizeMake(5.0f, 5.0f), NULL);
    CGLayerRelease(shapeLayer);

    UIGraphicsEndImageContext();
}

Please note that this is obviously the problem reduced to its simplest reproducible state. I'm using dynamic memory allocation because in my actual code the size of the array isn't known at compile time.

Upvotes: 2

Views: 912

Answers (1)

Martin R
Martin R

Reputation: 539735

I cannot tell you why Instruments reports that CGContext objects are leaking, and not CGLayer, but the layer created with

shapeLayers[i] = CGLayerCreateWithContext(context, CGSizeMake(5.0f, 5.0f), NULL);

must definitely be released with

CGLayerRelease(shapeLayers[i]); 

and not with

free(shapeLayers[i]);   

CGLayerCreateWithContext is not malloc, so calling free for that object can cause memory corruption.

Upvotes: 2

Related Questions