Ios 导致数据泄漏的NSD
我有一个CIos 导致数据泄漏的NSD,ios,swift,swift2,nsdata,Ios,Swift,Swift2,Nsdata,我有一个Cchar*cArray和它的长度,我需要将它转换为NSData 我是这样做的: var data: NSData? = NSData(bytesNoCopy: cArray, length: Int(length)) 它正在工作。问题是这会导致内存泄漏。我不知道为什么,但我可以在分配工具上看到它是malloc 64字节,当函数完成或我将其设置为null时不会释放它 这段代码被调用了很多,所以我需要它是免费的泄漏。我能做些什么来防止泄漏 编辑:这是代码 func on_data_rec
char*cArray
和它的长度,我需要将它转换为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)
}
func on_data_recv_fn(buf:UnsafeMutablePointer,length:CInt,user_data:UnsafeMutablePointer)->CInt{
守卫buf!=没有其他{
NSLog(“数据记录中的buf为零”)
返回-1
}
//var数据:NSData?=NSData(字节nocopy:buf,长度:Int(长度),自由时长:true)
var数据:NSData?=NSData(字节nocopy:buf,长度:Int(长度))
让succeeedwriting=Int(PacketTunnelProvider.sendpackages(数据!))
数据=零
返回CInt(成功写入)
}
根据记忆仪器,这里有个漏洞。
sendPackets函数不保存数据,因此不存在问题
编辑:附加来自仪器的图像。
好吧,似乎由于某种原因,如果我使用autoreleasepool,一切都正常 由Objective-C支持的类型的内存管理是一个广泛而有趣的话题。例如,请参见此处: 您可能还发现这个问题很有用: 另外,如果传递给
on_data\u recv\u fn
的buf
是由某个C代码动态分配的,该代码稍后会尝试释放它,那么我认为这里有一个危险。另一种危险的可能性是:该函数是用Swift实现的回调函数,由C代码调用。在这种情况下,buf
可能位于堆栈上
我没有玩过这些场景,但根据NSData
文档,bytesnopy
初始值设定项使NSData
获得内存的所有权,然后取消分配它;它假定内存是使用malloc()
分配的,因此任何未使用malloc的内存都不应使用此初始值设定项来构造NSData
。见:
还有其他的NSData
初始化器可以复制缓冲区,在这些情况下会更安全。如果触发内存警告会发生什么?内存是否被释放?bytesNoCopy初始值设定项不分配任何数据,它只获取给定的数据并将其包装到NSData对象中。奇怪的是,你在这一点上看到了malloc。你确定吗?缓冲区是从哪里来的?您需要确保它最终被解除分配。如果数据是用malloc分配的,那么NSData bytesNoCopy也将在解除分配NSData对象时解除分配。所以OP在这里应该只看到一个免费的但没有malloc。但是OP只看到一个malloc,没有免费的。真奇怪。我假设:仪器输出被曲解了。这是一个很好的问题。代码的细节似乎混淆了真正的问题。当我试图将使用arc编译的对象文件与那些被编码来执行自己的retain和release调用的对象文件混合使用时,我也发生了内存泄漏。我还从一个malloc'ed缓冲区创建了NSData对象,这个缓冲区是我从一个c代码获得的。我确信NSData本身正在泄漏一些东西,即使我将文件转换为手动内存管理并自己发布了NSData。但你下面的解决方案成功了。将该块包装在@autoreleasePool{}块中,泄漏就消失了。