简体   繁体   中英

will reassign a pointer cause memory leak?

I have the following code and wondering what will happen when iOS is recollecting the allocated memories. Will the memory p1 pointed to get autoreleased afterwards, although it's pointing to a different memory now? And also will the memory p2 pointed to get autoreleased as well, as p1 is semantically meant to point to autoreleased memory at the beginning?

NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:10];
NSMutableArray *p2 = [[NSMutableArray alloc] init];

// what will happen to the memory p1 and p2 point to
// after the following assignment, and at later stage?
p1 = p2;

Nothing will be leaked, p1 is an autoreleased object, in that scenario, after you assign p2 to p1, both of them simply point to the same object. Original object that p1 was pointing to, is managed by autorelease pool and will be released when the pool is drained. ARC or not, there is no leak assuming that you release p2 later.

Under ARC, you won't need to do anything Both objects will be released. Outside of ARC:

NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:10];

returns an autoreleaed value. You don't need to release this value. However, this:

NSMutableArray *p2 = [[NSMutableArray alloc] init];

has a manual retain count of 1. You will need to release the value of p2 (which is then assigned to p1) when you are done with it.

NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:10];
NSMutableArray *p2 = [[NSMutableArray alloc] init];

// what will happen to the memory p1 and p2 point to
// after the following assignment, and at later stage?
p1 = p2;

" iOS is recollecting the allocated memories" - iOS never had Garbage Collection feature.

p1 is pointer pointing to autoreleased object.

p2 is pointer pointing to non-autoreleased object (you or ARC has to release it later to avoid memory leak)

After p1 = p2, p1 points to non-autoreleased object that p2 is pointing to. Original object p1 was pointing to is orphaned at this point.

If you are using ARC feature, you don't have to do anything. Under Manual memory management environment you do [p2 release]; or [p1 release]; to balance releasing of allocated object that you own.

By the way, if you ever have questions like this in the future, it's easily tested by (a) subclassing the class in question; and (b) adding your own dealloc that logs the deallocation. For example:

@interface TestNSMutableArray : NSMutableArray
@end

@implementation TestNSMutableArray
- (void)dealloc
{
    [super dealloc]; // only needed for non-ARC
    NSLog("%s", __FUNCTION__);
}
@end

Then try your code using TestNSMutableArray rather than NSMutableArray . If you see your dealloc , you're good. If not, you're leaking.

Clearly you can also use Instruments, but when I was first getting my hands around Objective-C memory handling, I found this to be a simple, though useful, diagnostic technique.

First, this depends on if you are using ARC.

Using ARC: There will be no memory leaks. The OS will release the memory for p1 and the array will now point to the same location as p2. Then, the OS will release the memory for both arrays when p1 and p2 go away (such as when the class is deallocated).

No ARC: p1 will be leaked. To fix the leak you will need

[p1 release];

before assigning the value of p2 to p1. If you do not call release on both of these arrays before the class is deallocated, the memory from p2 will be leaked also.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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