XelharK
XelharK

Reputation: 609

Memory leak in CGImage

I've got a memory leak i just don't know how to solve.

This is the leaking code:

[newImg release];
CGColorSpaceRef d_colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =  CGBitmapContextCreate(Data, width, 
                                              height, 
                                              8, 4*width, 
                                              d_colorSpace, 
                                              kCGImageAlphaNoneSkipFirst);
UIGraphicsPushContext(context);
CGImageRef new_img = CGBitmapContextCreateImage(context);
UIImage * convertedImage = [[UIImage alloc] initWithCGImage:
                             new_img];
CGImageRelease(new_img);
CGContextRelease(context);
CGColorSpaceRelease(d_colorSpace);
newImg = convertedImage;

I modify pixel information stored in Data, then with this method i create a UIImage back from the Data (which is as unsigned char array)

The xcode instruments tells me that there are leaks in here:

CGImageRef new_img = CGBitmapContextCreateImage(context);

And here:

UIImage * convertedImage = [[UIImage alloc] initWithCGImage:
                             new_img];

though i release both of them :( Can somebody tell me how to solve this?

Thanks in advance ^-^

Upvotes: 1

Views: 5585

Answers (4)

Rob Napier
Rob Napier

Reputation: 299355

Almost certainly you are failing to release newImg somewhere else in your code. Perhaps you are not releasing it in -dealloc. If this is true, then Instruments will flag the line of code that allocated the memory. It doesn't know when you should or shouldn't have released; it just knows when the memory was allocated and when it was freed. You'll need to audit your code for how you manage this ivar.

That said, you are directly accessing your ivars, which is bad. This is the #1 cause of memory problems in ObjC. Use properties and accessors (except in init and dealloc), and these problems will tend to go away. (And convert to ARC. There is very seldom a reason to use manual retain counting anymore, particularly on iOS. Still, even with ARC, I recommend using accessors and not touching your ivars directly.)

Also: do not call your property newImg. The prefix new has a special meaning in ObjC (it means that the returned object should have a effective +1 retain count). This can cause you memory problems and false-positive warnings. It should have a name like convertedImage or nextImage.

Upvotes: 1

FreeNickname
FreeNickname

Reputation: 7764

Seems to me that you don't release convertedImage Try to replace this line

UIImage * convertedImage = [[UIImage alloc] initWithCGImage:
                             new_img];

with this one

UIImage * convertedImage = [[[UIImage alloc] initWithCGImage:
                             new_img] autorelease];

in your code.

And if I understand you correctly (based on comments to question), you declare newImg property like so:

@property (nonatomic, retain) UIImage* newImg; //or something like that

In this case the synthesized setter for this property will retain any object that will be assigned to it. And release it when the value will change. So you are not responsible for releasing it and you should remove this line:

[newImg release];

I guess, the best thing you can do is to read Advanced Memory Management Programming Guide. It isn't too long and yet it provides a complete overview of main conventions used in iOS memory management.

And since you also work with CoreFoundation objects/functions, consider the Memory Management Programming Guide for Core Foundation.

I hope it will help :)

Upvotes: 0

Vladimir Gritsenko
Vladimir Gritsenko

Reputation: 1683

CGBitmapContextCreate won't release the Data you give it. Either give it NULL (in which case the context will manage its own backing memory) or release it yourself after you release the context.

EDIT: here is the relevant documentation.

Upvotes: 0

pheelicks
pheelicks

Reputation: 7469

Edit: Original post did not seem to help, so deleting and re-posting.

Try this instead:

//[newImg release]; DELETE THIS LINE
CGColorSpaceRef d_colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =  CGBitmapContextCreate(Data, width, 
                                              height, 
                                              8, 4*width, 
                                              d_colorSpace, 
                                              kCGImageAlphaNoneSkipFirst);
UIGraphicsPushContext(context);
CGImageRef new_img = CGBitmapContextCreateImage(context);

newImg = [UIImage imageWithCGIImage:new_img];

CGImageRelease(new_img);
CGContextRelease(context);
CGColorSpaceRelease(d_colorSpace);

Have tested this and it does not leak on my end.

Upvotes: 0

Related Questions