2

我对一件奇怪的事情感到困惑......我有一个 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 并在调用这个方法后释放它......但没有什么有趣的......

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

4

2 回答 2

1

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

当我释放这个 unsigned char 并再次分配它时,我看到它在内存中保留了上次分配的相同地址

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

我的问题是,由于这种分配,每 2 秒发生一次,我有内存泄漏......但是当我尝试释放分配的内存扇区时,会发生上述情况......:(

如果有泄漏,很可能是在调用该方法的代码中,因为这里没有明显的泄漏。语义显然是调用者负责释放缓冲区。那么这是怎么做到的呢?

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

确保您的内存得到最新更新的一种简单方法是将您自己的数据写入其中。您可以用计数器填充缓冲区,并在方法之外验证这一点。例如,就在您返回之前rawData

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

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

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

于 2012-06-04T12:38:53.750 回答
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); 到这里问题就解决了......谢谢大家

于 2012-06-05T14:48:20.127 回答