unsigned char alloc和free issue

时间:2012-06-04 10:57:27

标签: objective-c free alloc unsigned-char

我对一个奇怪的事情感到困惑....我有一个unsigned char数组....我使用calloc分配它并在其中记录一些字节数据...但是当我释放这个unsigned char并分配它时再次,我看到它在内存中保留了相同的地址,这是前一次分配的。我理解为什么......但是我无法理解为什么我第二次尝试写入的数据不是写的...有写入第一次写的数据....有人可以解释一下吗? ??????

unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));

这就是我分配它的方式.... 实际上我的问题是,由于这个分配,每2秒发生一次我有内存泄漏...但是当我尝试释放分配的内存扇区发生的事情上面描述.... :(

如果有人可以帮助我......我会很高兴的...... 这是代码......

- (unsigned char*) createBitmapContext:(UIImage*)anImage{

CGImageRef imageRef = [anImage CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
bytesPerPixel = 4;
bytesPerRow = bytesPerPixel * width;

NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);

CGContextRelease(context);

imageRef=nil;
return rawData; }

在这段代码中没有我自由的部分(rawData),因为我无法在这个方法中释放它我尝试全局定义rawData并在调用此方法后释放它...但没什么有趣的....

如果有人可以帮助我......我会很高兴的......

2 个答案:

答案 0 :(得分:1)

好的,所以这个方法将UIImage呈现为新分配的字节缓冲区并将缓冲区返回给调用者。由于您使用calloc分配它,它将初始化为0,然后用图像内容覆盖。

  

当我释放这个unsigned char并再次分配它时,我发现它在内存中保留了相同的地址,这是前一次分配的

是的,无法保证缓冲区在内存中的位置。假设您在返回的内存上调用free(),请求完全相同的大小很可能会为您提供相同的缓冲区。但是 - 你怎么验证内容不是第二次写的?缓冲区中 是什么?

  

我的问题是因为这个分配,每2秒发生一次我有内存泄漏...但是当我尝试释放分配的内存扇区发生的事情上面描述.... :(

如果存在泄漏,则可能在代码中调用此方法,因为此处没有明显的泄漏。语义显然是调用者负责释放缓冲区。那怎么办?

另外,您是否验证CGBitmapContext是否正确创建?某些创建标志或参数可能会导致错误。因此,添加context有效的检查(至少不是nil)。这可以解释为什么内容没有被覆盖。

确保您的记忆新近更新的一种简单方法是将自己的数据写入其中。您可以使用计数器填充缓冲区,并在方法外验证。例如,在您返回rawData之前:

static unsigned updateCounter = 0;
memset(rawData, updateCounter & 0xff, width*height*4);

这将循环写入0-255进入缓冲区,您可以轻松验证。

另一件事 - 你想用这段代码实现什么?可能有一种更简单的方法来实现您想要实现的目标。返回没有元数据的裸缓冲区不一定是管理图像的最佳方式。

答案 1 :(得分:0)

所以大家好我解决了这个问题......首先我将createBitmapContext方法更改为

- (void) createBitmapContext:(UIImage*)anImage andRawData:(unsigned char *)theRawData{

CGImageRef imageRef = [anImage CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
bytesPerPixel = 4;
bytesPerRow = bytesPerPixel * width;

NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(theRawData, width, height,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);

CGContextRelease(context);
imageRef=nil;
//    return theRawData;}

然后......除此之外,我错过了我将newRawData分配给oldRawData的部分,并且由此我有两个指向相同内存地址的指针......所以从这里出现问题...我将此分配部分更改为这个memcpy(rawDataForOldImage,rawDataForNewImage,newCapturedImage.size.width * newCapturedImage.size.height * 4);在这里问题解决了....感谢所有