C and Objective-C - The correct way to free an unsigned char pointer

in my application 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 this pointer like this: self.bitmapData = [image getRawData];

Where in this process can I free this malloc'd memory? When I try to free a property in dealloc, it gives me an exc_bad_access error. I feel like I am missing the fundamental concept of c or objective-c. All help is appreciated.

+6
source share
2 answers

There is a good discussion about the security of using malloc / free in objective-c here .

As long as you free () the memory you malloc () correctly, there should be no problem.

I personally find that using NSMutableData or NSMutableArray is simply simpler. If you do not need maximum performance, I would not use C malloc / free directly.

+6
source

One way to solve this problem is to use NSMutableData, so you can replace

 unsigned char *rawData = malloc(height * width * 4); 

from

 myData = [[NSMutableData alloc] initWithCapacity:height * width * 4]; unsigned char *rawData = myData.mutableBytes; 

you can free myData in your expander.

alternatively you can do

 myData = [NSMutableData dataWithCapacity:height * width * 4]; 

This means that your myData is stored around the duration of the event loop, you can even change the type of the returned getRawData method to return NSMUtableData or NSData, and thus it can be saved by other parts of your code, the only time I return unprocessed bytes to my code, if I know that it will be available for the life of the object that returns it, so if I need to hold the data, I can save the owner class.

Apple often uses

 myData = [[NSMutableData alloc] initWithCapacity:height * width * 4]; unsigned char *rawData = myData.mutableBytes; 

and then document that if you need bytes that go beyond the current autorun cycle, you will have to copy it.

+4
source

Source: https://habr.com/ru/post/893950/


All Articles