Hello All,
I have an object that holds a pointer to some malloced memory, when I come to dealloc the object I use the free command to free up the malloced memory, how ever the free command appears to be absolutely doing nothing and I'm getting large memory leaks as a result. I have confirmed that the dealloc command is being executed.
Header
//
// Copyright 2010 None. All rights reserved.
//
@interface BufferedImage : NSObject {
CGColorSpaceRef colorSpace;
unsigned char *data;
uint32_t* dataInt;
size_t width;
size_t height;
size_t bitsPerComponent;
size_t bytesPerPixel;
size_t bytesPerRow;
size_t dataSize;
size_t power_w;
size_t power_h;
size_t origin_ajust;
size_t width_bits;
}
@property CGColorSpaceRef colorSpace;
@property unsigned char *data;
@property uint32_t* dataInt;
@property size_t width;
@property size_t height;
@property size_t bitsPerComponent;
@property size_t bytesPerPixel;
@property size_t bytesPerRow;
@property size_t dataSize;
@property size_t power_w;
@property size_t power_h;
@property size_t origin_ajust;
@property size_t width_bits;
-(BufferedImage*) initWithW:(size_t) w
h:(size_t) h;
-(UIImage*)getUIImage;
-(void)setABGRatX:(int) x
y:(int) y
integer:(uint32_t) integer;
-(CGContextRef)getCGContext;
-(uint32_t)getABGRatX:(int) x
y:(int) y;
-(void)maskABGRatX:(int) x
y:(int) y
integer:(uint32_t) integer;
-(void)maskWithBufferedImageAtX:(int) nx
y:(int) ny
image:(BufferedImage*) image;
-(void)setAsImage:(BufferedImage*) image;
@end
Main
//
// Copyright 2010 None. All rights reserved.
//
#import "BufferedImage.h"
@implementation BufferedImage
@synthesize colorSpace;
@synthesize data;
@synthesize dataInt;
@synthesize width;
@synthesize height;
@synthesize bitsPerComponent;
@synthesize bytesPerPixel;
@synthesize bytesPerRow;
@synthesize dataSize;
@synthesize power_w;
@synthesize power_h;
@synthesize origin_ajust;
@synthesize width_bits;
- (void)dealloc
{
CGColorSpaceRelease(self.colorSpace);
free(self.data);
self.data = 0;
[super dealloc];
}
-(CGContextRef)getCGContext{
@synchronized(self) {
return CGBitmapContextCreate(self.data, self.power_w, self.power_h,
self.bitsPerComponent, self.bytesPerRow, self.colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
// return context;
}
}
-(UIImage*)getUIImage{
@synchronized(self) {
CGContextRef context = CGBitmapContextCreate(self.data, self.power_w, self.power_h,
self.bitsPerComponent, self.bytesPerRow, self.colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage *result = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGContextRelease(context);
return result;
}
}
-(BufferedImage*)init{
return [self initWithW:320 h:480];
}
-(BufferedImage*) initWithW:(size_t) w
h:(size_t) h{
CGColorSpaceRef colorS = CGColorSpaceCreateDeviceRGB();
size_t bitsPerC = 8;
size_t bytesPerP = 4;
size_t bytesPR = (w * bitsPerC * bytesPerP + 7) / 8;
size_t dataS = bytesPR * h;
unsigned char *d = malloc(dataS);
memset(d, 0, dataS);
CGContextRef con = CGBitmapContextCreate(d, w, h,
bitsPerC, bytesPR, colorS,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGImageRef imageRef = CGBitmapContextCreateImage(con);
UIImage *result = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGColorSpaceRelease(colorS);
CGContextRelease(con);
free(d);
return [self initWithImage:result];
}
-(BufferedImage*)initWithImage:(UIImage*)source
{
if(self = [super init]){
CGImageRef sourceRef = source.CGImage;
self.width = CGImageGetWidth(sourceRef);
self.height = CGImageGetHeight(sourceRef);
power_w = 1;
while (power_w < self.width) {
power_w <<= 1;
}
uint32_t n = power_w - 1;
width_bits = 0;
while (n) {
width_bits += n & 0x1u;
n >>= 1;
}
//self.width;//512;
//512;
power_h = self.height;// + 20; // As we are not using it for scrolling we can get away with this //1;
//while (power_h < self.height) {
// power_h <<= 1;
//}
origin_ajust = power_h - 1;
self.colorSpace = CGColorSpaceCreateDeviceRGB();
self.bitsPerComponent = 8;
self.bytesPerPixel = 4;
self.bytesPerRow = (power_w * self.bitsPerComponent * self.bytesPerPixel + 7) / 8;
self.dataSize = self.bytesPerRow * power_h;
self.data = 0;
self.data = malloc(self.dataSize);
memset(self.data, 0, self.dataSize);
self.dataInt = (uint32_t*) self.data;
CGContextRef context = CGBitmapContextCreate(self.data, power_w, power_h,
self.bitsPerComponent, self.bytesPerRow, self.colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextDrawImage(context, CGRectMake(0, 0, self.width, self.height), sourceRef);
//free(self.data);
CGContextRelease(context);
}
return self;
}
-(void)setABGRatX:(int) x
y:(int) y
integer:(uint32_t) integer{
int byteIndex = ((origin_ajust-y) << width_bits) + x;
self.dataInt[byteIndex] = integer;
}
-(void)maskWithBufferedImageAtX:(int) nx
y:(int) ny
image:(BufferedImage*) image{
for (int i = 0; i < image.height; i++) {
int newy = i + ny;
uint32_t * copy = self.dataInt;
uint32_t * copy2 = image.dataInt;
copy += ((self.origin_ajust-newy) << self.width_bits) + nx;
copy2 += ((image.origin_ajust-i) << image.width_bits);
for (int j = 0; j < image.width; j++) {
*copy &= *copy2;
copy++;
copy2++;
}
}
}
-(void)setAsImage:(BufferedImage*) image{
for (int i = 0; i < image.height; i++) {
uint32_t * copy = self.dataInt;
uint32_t * copy2 = image.dataInt;
copy += ((self.origin_ajust-i) << self.width_bits);
copy2 += ((image.origin_ajust-i) << image.width_bits);
for (int j = 0; j < image.width; j++) {
*copy = *copy2;
copy++;
copy2++;
}
}
self.width = image.width;
self.height = image.height;
}
-(void)maskABGRatX:(int) x
y:(int) y
integer:(uint32_t) integer{
int byteIndex = ((origin_ajust-y) << width_bits) + x;
self.dataInt[byteIndex] &= integer;
}
-(uint32_t)getABGRatX:(int) x
y:(int) y {
y = (y>origin_ajust)?(origin_ajust):(y); // A fixes a bug that happens on the device but not in the simulator.
@synchronized(self) {
//int byteIndex = (power_w * (origin_ajust-y)) + x;
int byteIndex = ((origin_ajust-y) << width_bits) + x;
return self.dataInt[byteIndex];
}
}
@end
Thanks in advance.