2012-06-04 29 views
2

我很困惑一個奇怪的事情....我有一個無符號字符數組....我使用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並釋放它...但沒有什麼有趣的...。 ...我會很高興...

+0

您將需要提供一個完整的代碼片段,顯示分配和緩衝區寫入,以及如何驗證內容。以上是不足以回答你的問題。 – gavinb

+0

@gavinb完成...任何有趣的想法? – Garnik

回答

1

好的,所以這種方法是渲染一個UIImage到新分配的字節緩衝區並返回緩衝區給調用者。由於您使用calloc進行分配,因此它將被初始化爲0,然後被圖像內容覆蓋。

當我釋放此無符號的字符,然後重新分配,我看到它保留其被分配前一次

在內存中的同一地址

是的,有沒有關於緩衝區的位置保證在記憶中。假設您在返回的內存上調用free(),請求完全相同的大小很可能會給您返回相同的緩衝區。但是 - 你如何驗證內容不會被第二次寫入?什麼在緩衝區中?

我的問題是,由於這種分配,其中發生一次,每2秒我有內存泄漏的......但是當我嘗試釋放所分配的內存部門發生上述事情.... :(

如果發生泄漏,很可能是調用此方法的代碼,因爲這裏沒有明顯的泄漏,語義顯然是這樣的,調用者負責釋放緩衝區,那麼這是如何實現的?

此外,您是否驗證CGBitmapContext正在創建?可能是這樣我創建標誌或參數可能會導致錯誤。因此,添加context有效的支票(至少不是零)。這可以解釋爲什麼內容沒有被覆蓋。

一個簡單的方法,以確保你的記憶被新鮮更新是您自己的數據寫入。您可以用計數器填充緩衝區,並在方法外驗證。通過寫0-255到緩衝區,您可以輕鬆地驗證

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

這將循環:例如,剛剛返回rawData之前。

另一件事 - 你想用這段代碼實現什麼?可能有更簡單的方法來實現你想要達到的目標。返回沒有元數據的裸緩衝區不一定是管理圖像的最佳方式。

+0

我的項目的目標是編寫屏幕共享工具。使用這種方法,我想獲得像素顏色並與以前的圖片進行比較以獲得相似度。然後在其他方法中,我得到這兩個圖片的差異,併發送改變的部分。所有這些部分都完成了,但我有這個泄漏。我確信,因爲我每次都會得到下一張照片。而且我也嘗試將內存設置爲零memset(rawData,0,weight * height * 4);我釋放它之後,但仍然是一樣的。我明白爲什麼它每次都返回相同的地址,但我不明白爲什麼CGBitmapContextCreate方法不會覆蓋裏面的數據。 – Garnik

+0

而且我敢肯定,泄漏是在rawData的分配...檢查了百種方法... – Garnik

+0

是啊我知道param的順序...但這不會幫助我 – Garnik

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);並在這裏問題解決了....感謝所有