2016-02-29 56 views
1

我有一個C char *cArray,它的長度,我需要將其轉換爲NSData的 我做它:的NSData造成泄漏

var data: NSData? = NSData(bytesNoCopy: cArray, length: Int(length)) 

,它的工作。問題是這導致了一些內存泄漏。我不知道爲什麼,但是我可以在分配工具中看到它是malloc 64字節,並且在函數完成時或將其設置爲null時不會釋放它。

此代碼被稱爲很多,所以我需要它是無泄漏的。我能做些什麼來防止泄漏?

編輯:這是代碼

func on_data_recv_fn(buf: UnsafeMutablePointer<CChar>, length: CInt, user_data: UnsafeMutablePointer<Void>) -> CInt { 
    guard buf != nil else { 
     NSLog("on_data_recv_fn buf is nil") 
     return -1 
    } 

    //var data: NSData? = NSData(bytesNoCopy: buf, length: Int(length), freeWhenDone: true) 
    var data: NSData? = NSData(bytesNoCopy: buf, length: Int(length)) 
    let succeededWriting = Int(PacketTunnelProvider.sendPackets(data!)) 
    data = nil 
    return CInt(succeededWriting) 
} 

根據存儲工具,這裏有一個泄漏。 sendPackets函數沒有保存數據,所以問題不存在。

編輯:附上儀器的圖像。 instruments image

+0

完整的方法代碼請。 – Darko

+0

查看編輯答案 – Roee84

+1

如果觸發內存警告會發生什麼?內存是否被釋放? – Darko

回答

2

嗯,似乎如果我使用autoreleasepool一切都可以出於某種原因。

1

由Objective-C支持的類型的內存管理是一個廣泛而有趣的話題。見,例如,在這裏:

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html

您也可以找到這個問題的有用:

Is it necessary to use autoreleasepool in a Swift program?

另外,我覺得有一種危險在這裏如果傳遞給on_data_recv_fnbuf是動態由一些C代碼分配,後者試圖釋放它。另一個危險的可能性:該函數是一個在Swift中實現的回調函數,並由C代碼調用。在這種情況下,buf可能在堆棧中。

我還沒有任何方案中播放,但是根據NSData文檔中,bytesNoCopy初始化使得存儲器的NSData取所有權,然後解除分配;它假定內存是使用malloc()分配的,因此不應使用任何不是malloc'd的內存來構造使用此初始化程序的NSData。請參閱https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/#//apple_ref/occ/instm/NSData/initWithBytesNoCopy:length

還有其他NSData初始化程序可以複製緩衝區,並且在這些情況下可以更安全。