2011-06-23 78 views
0

我有一個類中的方法,它somethign這樣的:的NSData的dataWithBytesNoCopy和將writeToFile

@implementation NSData (additions) 
- (id)someFunc { 

char *buffer = malloc(255); 
NSUInteger length = 0; 
while (true) { 
    // . . . fill buffer[length++]; 
} 

realloc(buffer, length); 
return [NSData dataWithBytesNoCopy:buffer length:length freeWhenDone:NO]; 
} 

然後我想寫返回的數據(也稱之爲NSData的* FILEDATA):

NSError *error; 
NSData fileData = [NSData someFunc]; 
[fileData writeToFile:somePath options:NSDataWritingAtomic error:&error]; 

我收到一個錯誤:

Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed. (Cocoa error 512.)" UserInfo=0x20deffd0 {NSFilePath=/Users/user/Library/Application Support/iPhone Simulator/4.3/Applications/4C315580-153D-4FA7-9474-E17B58832515/Library/Caches/file.pdf, NSUnderlyingError=0x20de1fe0 "The operation couldn’t be completed. Bad address"}

該路徑存在且有效。我認爲問題是返回的NSData僅僅是一個用malloc分配的數組的輕量包裝,writeToFile不知道如何處理這個問題。有沒有人看到我在做什麼錯了?

+0

您需要保存由realloc的返回地址:'緩衝區= realloc的(緩衝區長度);' – DarkDust

+0

@DarkDust這是問題,請做出回答我會接受它。 –

回答

1

當您撥打realloc時,您必須保存返回的指針,因爲realloc可能會分配新緩衝區並將舊位置的內容複製到該新位置。之後舊位置爲free d,因此無效。不同的malloc調用可能會覆蓋舊的位置。

所以,你需要做的:

buffer = realloc(buffer, length); 
+1

這不適用OP代碼的結構。即循環後的'realloc()'沒有任何用處。如果輸入數據對於原始'malloc(255)'來說太大了,那麼內存已損壞。 – bbum

0

該代碼沒有任何意義。

  • 表明您使用填充緩衝區

  • 代碼你有一個malloc(),爲什麼在循環之後你realloc的()?這是浪費週期,並且如果目標是如果輸入數據太長而擴大緩衝區,則它不會像寫入那樣工作。

  • 你必須檢查返回值writeToFile:options:error:知道是否有錯誤;你不能直接檢查錯誤。

  • 另外,不要將這樣的類別粘貼到現有的類上。一般來說,這表明一個架構很脆弱,層次分明。如果你確實走這條路線,至少給你的方法加上一些獨特的東西。

目前尚不清楚爲什麼會出現特定的錯誤。這條路似乎有點不可思議,你是怎麼產生它的?

+0

填充緩衝區的代碼最終並不重要,但我可以看到應該如何包含它。調用realloc是因爲它正在解碼base64編碼的字符串,並且原始緩衝區可能比最終實際使用的字節大得多。我不清楚我如何閱讀錯誤,但我確實使用了writeToFile:options:error。而且我不親自使用類別,代碼由Wsdl2Obj c生成,該工具從Web服務描述中生成Objective-C代碼。感謝您仍然嘗試回答。 –

+0

使用循環外的realloc沒有任何意義,很可能會導致內存粉碎機。如果沒有重構代碼,DarkDust的建議將無法工作(除非數據比原始緩衝區小,使得realloc毫無意義)。 – bbum