【问题标题】:C and Objective-C - Correct way to free an unsigned char pointerC 和 Objective-C - 释放无符号字符指针的正确方法
【发布时间】:2011-10-16 15:19:06
【问题描述】:

在我的应用程序中,我使用此函数创建了一个无符号字符指针:

- (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;
}

在另一个类中,我为该指针分配了一个属性,如下所示:self.bitmapData = [image getRawData];

在这个过程中,我可以在哪里释放 malloc 的内存?当我尝试释放 dealloc 中的属性时,它给了我一个 exc_bad_access 错误。我觉得我在这里缺少一个基本的 c 或 Objective-c 概念。感谢所有帮助。

【问题讨论】:

  • 你如何释放财产?
  • 每个分配器都有一个配对的解除分配器来释放分配的对象。查看malloc 的手册页——但最好找到与您的特定平台相关的文档——将解释应该使用什么;-)
  • 我尝试了 free(property) 这似乎不正确,但我还是试了一下。

标签: objective-c c pointers malloc free


【解决方案1】:

解决此类问题的一种方法是使用 NSMutableData,因此您可以替换

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

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

然后您可以在您的释放器中释放 myData。

你也可以这样做

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

这将意味着您的 myData 在事件循环期间保持不变,您甚至可以更改 getRawData 方法的返回类型以返回 NSMUtableData 或NSData,这样它可以被代码的其他部分保留,我在代码中返回原始字节的唯一时间是如果我知道它在返回它的对象的生命周期内可用,如果我需要的话保留数据我可以保留所有者类。

苹果会经常使用

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

模式,然后记录如果您需要超出当前自动释放池周期的字节,则必须复制它。

【讨论】:

  • 但这不是同样的问题吗,只是现在使用对象而不是原始指针?必须释放对象,必须释放原始指针。在这两种情况下,设计都应该非常清楚何时可以丢弃它们。
  • 处理对象更容易,因为您可以遵守保留/释放规则。如果你从一个方法返回原始字节,你怎么知道方法的调用者正确地管理内存,如果方法的调用者对返回的字节不感兴趣怎么办。如果字节是从私有方法返回的,那么你可以做任何你喜欢的事情,但如果它是公共接口的一部分,那么你就不需要记住你 6 个月前写的那个方法了以通常的方式行事,坚持一套简单的规则要简单得多。
  • 这就是为什么我不会归还内存。我会告诉调用者它必须有多大,然后调用者可以传递他或她分配给你的缓冲区。您只需填充缓冲区。这样一来,所有权就更清晰了,IMO。
  • 是的,这是我经常采用的好方法,但在某些情况下,恢复 NSData 的 autoreleased 的字节很有用,我认为一些 NSString 方法会这样做 - [NSString UTF8String]
【解决方案2】:

在objective-c here中有很好的讨论使用malloc/free的安全性。

只要你正确地释放()你 malloc() 的内存,应该没有问题。

我个人认为使用 NSMutableData 或 NSMutableArray 更简单。如果你不需要极致性能,我不会直接使用 C malloc/free 语句。

【讨论】:

  • 这帮助我找到了实际上与我使用免费无关的答案。使用免费(self.property);不正确。 掌心。我试过免费(财产);效果很好。未来我相信我会使用 NSData 来避免 malloc 的麻烦。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多