简体   繁体   English

ARC下dataWithBytesNoCopy的内存泄漏?

[英]Memory leak with dataWithBytesNoCopy under ARC?

I have an NSData instance but I'm only interested in the data at a given offset. 我有一个NSData实例,但是我只对给定偏移量的数据感兴趣。 I considered using dataWithBytesNoCopy:length:freeWhenDone: to prevent copying the data, but it occurred to me I don't really realise what's happening: 我考虑过使用dataWithBytesNoCopy:length:freeWhenDone:来防止复制数据,但是它发生在我身上,我并没有真正意识到发生了什么:

self.data = [NSMutableData dataWithBytesNoCopy:(void *)(self.data.bytes + offset)
                                        length:self.data.length - offset
                                  freeWhenDone:NO];

I no longer have a pointer to the beginning of the data block, so I'm not sure how ARC handles this. 我不再有指向数据块开头的指针,因此我不确定ARC如何处理它。 The data block now points to the same block, but not at the beginning. 现在,数据块指向同一块,但不是在开头。 Does ARC deallocate the whole block when I'm done? 完成后,ARC是否会重新分配整个块? Is the data before the offset kept in the meanwhile? 同时保留偏移量之前的数据吗?

You're not leaking memory but, even worse, referring to freed memory: The new NSData instance will point to the storage maintained by the original NSData . 您不是在泄漏内存,更糟糕的是,是指释放的内存:新的NSData实例将指向由原始NSData维护的存储。 But the original instance will be released as soon as the new one is assigned. 但是原始实例将在分配新实例后立即释放。 From that point the new NSData contains a dangling pointer. 从那时起,新的NSData包含一个悬空指针。 Accessing the data is actually undefined behavior. 访问数据实际上是未定义的行为。

You should create a copy of the bytes: 您应该创建字节的副本:

self.data = [self.data subdataWithRange:(NSRange){ offset, self.data.length - offset }];

This way you're sure the new NSData actually owns the bytes it's pointing to. 这样,您可以确定新的NSData实际上拥有它指向的字节。

ARC can handle some situations involving pointers into an object, but there are restrictions. ARC可以处理某些涉及到对象的指针的情况,但是有一些限制。 Read Clang documentation on interior pointers . 阅读有关内部指针的Clang文档 HTH 高温超导

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM