user836218
user836218

Reputation:

Bad access on CGContextClearRect

I am getting the error EXC_BAD_ACCESS on the line CGContextClearRect(c, self.view.bounds) below. I can't seem to figure out why. This is in a UIViewController class. Here is the function I am in during the crash.

- (void)level0Func {
printf("level0Func\n");
frameStart = [NSDate date];

UIImage *img;
CGContextRef c = startContext(self.view.bounds.size);
printf("address of context: %x\n", c);
/* drawing/updating code */ {
    CGContextClearRect(c, self.view.bounds); // crash occurs here
    CGContextSetFillColorWithColor(c, [UIColor greenColor].CGColor);
    CGContextFillRect(c, self.view.bounds);

    CGImageRef cgImg = CGBitmapContextCreateImage(c);
    img = [UIImage imageWithCGImage:cgImg]; // this sets the image to be passed to the view for drawing
    // CGImageRelease(cgImg);
}
endContext(c);


}

Here are my startContext() and endContext():

CGContextRef createContext(int width, int height) {
CGContextRef r = NULL;
CGColorSpaceRef colorSpace;
void *bitmapData;
int byteCount;
int bytesPerRow;

bytesPerRow = width * 4;
byteCount = width * height;

colorSpace = CGColorSpaceCreateDeviceRGB();
printf("allocating %i bytes for bitmap data\n", byteCount);
bitmapData = malloc(byteCount);

if (bitmapData == NULL) {
    fprintf(stderr, "could not allocate memory when creating context");
    //free(bitmapData);
    CGColorSpaceRelease(colorSpace);
    return NULL;
}

r = CGBitmapContextCreate(bitmapData, width, height, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);

return r;
}

CGContextRef startContext(CGSize size) {
    CGContextRef r = createContext(size.width, size.height);
    // UIGraphicsPushContext(r); wait a second, we dont need to push anything b/c we can draw to an offscreen context
    return r;
}

void endContext(CGContextRef c) {
    free(CGBitmapContextGetData(c));
    CGContextRelease(c);
}

What I am basically trying to do is draw to a context that I am not pushing onto the stack so I can create a UIImage out of it. Here is my output:

wait_fences: failed to receive reply: 10004003
level0Func
allocating 153600 bytes for bitmap data
address of context: 68a7ce0

Any help would be appreciated. I am stumped.

Upvotes: 2

Views: 815

Answers (2)

rob mayoff
rob mayoff

Reputation: 385580

You're not allocating enough memory. Here are the relevant lines from your code:

bytesPerRow = width * 4;
byteCount = width * height;
bitmapData = malloc(byteCount);

When you compute bytesPerRow, you (correctly) multiply the width by 4 because each pixel requires 4 bytes. But when you compute byteCount, you do not multiply by 4, so you act as though each pixel only requires 1 byte.

Change it to this:

bytesPerRow = width * 4;
byteCount = bytesPerRow * height;
bitmapData = malloc(byteCount);

OR, don't allocate any memory and Quartz will allocate the correct amount for you, and free it for you. Just pass NULL as the first argument of CGBitmapContextCreate:

r = CGBitmapContextCreate(NULL, width, height, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);

Upvotes: 3

lorean
lorean

Reputation: 2150

Check that the values for self.view.bounds.size are valid. This method could be called before the view size is properly setup.

Upvotes: 0

Related Questions