in my app I create an unsigned char pointer using this function:
- (unsigned char*)getRawData
{
// First get the image into your data buffer
CGImageRef image = [self CGImage];
NSUInteger width = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = malloc(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), image);
CGContextRelease(context);
// Now your rawData contains the image data in the RGBA8888 pixel format.
return rawData;
}
And in another class I assign a property to that pointer like so: self.bitmapData = [image getRawData];
Where in this process can I free that malloc'd memory? When I try to free the property in dealloc, it gives me an exc_bad_access error. I feel like I'm missing a fundamental c or objective-c concept here. All help is appreciated.
There is a good discussion about the safety of using malloc/free in objective-c here.
As long as you correctly free() the memory that you malloc(), there should be no issue.
I personally think that using NSMutableData or NSMutableArray is just easier. If you don't need ultimate performance, I would not use the C malloc/free statements directly.
One way around this sort of issue is to use NSMutableData, so you can replace
unsigned char *rawData = malloc(height * width * 4);
with
myData = [[NSMutableData alloc] initWithCapacity:height * width * 4];
unsigned char *rawData = myData.mutableBytes;
you can then release myData in your deallocator.
alternativly you can do
myData = [NSMutableData dataWithCapacity:height * width * 4];
This will then mean your myData is kept around the the duration of the event loop, you can of cause even change the return type of getRawData method to return NSMUtableData or NSData, and that way it can be retained by other parts of your code, the only time I return raw bytes in my code is if I know it will be available for the life of the object that returns it, that way if I need to hold onto the data I can retain the owner class.
Apple will often use the
myData = [[NSMutableData alloc] initWithCapacity:height * width * 4];
unsigned char *rawData = myData.mutableBytes;
pattern and then document that if you need the bytes beyond the current autorelease pool cycle you will then have to copy it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With