2010-09-01 57 views
0

我在Objective-C中編寫項目,但我很依賴普通的C,因爲涉及到OpenGL。我分配的內存是寫入

我有我從文件中按以下方式讀取到內存中的數據blob:

NSString *path = [[NSBundle mainBundle] pathForResource:@"iPadTest" ofType:@""]; 
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path]; 
data = [file readDataToEndOfFile]; 
currentImage = [ReadDataFiles getOrganizedImageData:data]; 

最後一個函數給了我一個結構,其中的數據是有點更容易,但仍然存在爲三冗長數據斑點的圖像數據。它是這樣開始的:

ImageData *organizedImageData = malloc(sizeof(ImageData)); 

// IMAGE DIMENSIONS 
UInt64 *rawData = (UInt64 *) data.bytes; 
organizedImageData->imageDimensions.x = *rawData; 
rawData++; 
organizedImageData->imageDimensions.y = *rawData; 
rawData++; 
organizedImageData->imageDimensions.z = *rawData; 

// IMAGE 1 
rawData++; 
organizedImageData->image1Data = (UInt8*)rawData; 
// IMAGE 2 
rawData++; 
organizedImageData->image2Data = (UInt8*)rawData; 

// etc... 

的問題是,當數據到達OpenGL函數別的東西寫在相同的存儲。結果每次都不一樣,但數據永遠不會持續。

當我告訴調試器暫停,當這些地址被改變時,我最終在彙編代碼中,我不能做任何事情。

如何以及應該在哪裏分配內存空間,以便程序的其餘部分不會與其混淆?

+0

調試器在調用堆棧上顯示什麼?這是否給你一個線索? – torak 2010-09-01 14:37:11

+0

你能告訴我ImageData的結構是怎樣的嗎? – 2010-09-01 14:50:15

回答

2

問題是,您不擁有稱爲數據的變量,並且在您第一次遇到自動釋放池漏失(或者如果您使用GC,它在超出範圍後正在消失),它幾乎肯定會被釋放。當data消失時,您正在精心創建的指向[data bytes]的所有這些指針都處於懸浮狀態。

在引用計數的環境中,你需要發送-retaindata autorelease池排出之前(這是存在保證當您返回到運行循環發生),然後你需要釋放它,當你與完成數據在裏面。在GC環境中,您只需保留一個強大的參考,例如使它成爲某個對象的ivar。

或者,您可以將數據複製到其他位置,而不是僅創建指向其位的指針。

0

對不起,我不能發表評論,所以這裏有一個完整的答案:
像傑里米說,你沒有自己的參考data,所以它會消失!

有,然而,一個確保它幾種方法的可行性:

  1. 商店data(我真的是指針在這裏!)你的結構中,所以你可以釋放它,當你用它做。
    如果您在GC下運行,請將該字段定義爲__strong void *或(因爲NSData是免費橋接到CFData)請致電CFRetain((CFDataRef) data)其中is actually not a noop in GC-ed code! (您已經在GC-參考計數環境中報道了BTW ...)
  2. 通過[[NSData alloc] initWithContentsOfFile:]創建該對象並將其存儲到您的結構中。 (GC-notes也適用於此!)
  3. malloc您的圖像的內存和使用-[NSData getBytes:range:]與此。
    雖然這可能意味着一個明顯的性能問題。

您選擇哪種方式,不要忘記後yourself- CFRelease()很可能會在1的情況下最好的解決方案和2清理,因爲它涵蓋了GC和ref計數。


BTW(我希望這不會粗魯脫落!):
有沒有......

  1. 您使用NSFileHandle,而不是通過NSData直行有一定道理的-方法?
  2. 你有你的數據作爲blob的方式?
    您可以通過NSKeyedArchiver將它存儲爲二進制plist,並通過指針體操來檢索它稍微優雅一點,然而開銷不大。

哦,大單:
什麼究竟你做/想在這裏做的事:

// IMAGE 1 
organizedImageData->image1Data = (UInt8 *)rawData; 
rawData++; 
// IMAGE 2 
organizedImageData->image2Data = (UInt8 *)rawData; 
rawData++; 

我不能讓那多大意義。
建議2可能會簡化這一點,順便說一下:-)