我对一件奇怪的事情感到困惑......我有一个无符号的字符数组....我使用 calloc 分配它并在其中记录一些字节数据......但是当我释放这个无符号字符并再次分配它时,我看到它在内存中保留了上次分配的相同地址。我明白为什么...但是我不明白为什么我第二次尝试在那里写入的数据没有写入......有写第一次写的数据....谁能解释一下???????
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 并在调用此方法后释放它......但没什么有趣的....
如果有人可以帮助我,请...我会很高兴...
好的,所以这个方法是将UIImage
渲染到新分配的字节缓冲区中,并将缓冲区返回给调用方。 由于您使用 calloc
分配它,它将被初始化为 0,然后用图像内容覆盖。
当我释放这个无符号字符并再次分配它时,我看到它在内存中保留了上次分配的相同地址
是的,无法保证缓冲区在内存中的位置。 假设您在返回的内存上调用free()
,请求完全相同的大小很可能会为您提供相同的缓冲区。 但是 - 您如何验证内容没有第二次写入? 缓冲区中有什么?
我的问题是,由于这种分配,每 2 秒发生一次,我有内存泄漏......但是当我尝试释放分配的内存扇区时,会发生上述事情..:(
如果存在泄漏,则很可能在调用此方法的代码中,因为此处没有明显的泄漏。 语义显然是这样的,调用方负责释放缓冲区。 那么这是怎么做到的呢?
另外,您是否正在验证是否正确创建了CGBitmapContext
? 某些创建标志或参数可能会导致错误。 因此,添加检查context
是否有效(至少不是零)。 这可以解释为什么内容没有被覆盖。
确保内存是最新更新的一种简单方法是将自己的数据写入其中。 您可以使用计数器填充缓冲区,并在方法外部进行验证。 例如,在您返回之前rawData
:
static unsigned updateCounter = 0;
memset(rawData, updateCounter & 0xff, width*height*4);
这将循环将 0-255 写入缓冲区,您可以轻松验证。
另一件事 - 你想用这段代码实现什么? 可能有一种更简单的方法来实现您想要实现的目标。 返回没有元数据的裸缓冲区不一定是管理图像的最佳方式。
所以伙计们我解决了这个问题...第一件事,我将创建位图上下文方法更改为此
- (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);到这里问题解决了....感谢大家