未签名的字符分配和免费问题



我对一件奇怪的事情感到困惑......我有一个无符号的字符数组....我使用 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);到这里问题解决了....感谢大家

最新更新