views:

242

answers:

2

Obviously the following in the main method should lead to a leak:

NSMutableArray *strings = [[NSMutableArray alloc] init];
[strings addObject:@"Hello"];
[strings addObject:@"Howdy"];

return 0;

and the clang LLVM reports the leak. However, working through the Hillegass book, I tried analyzing the following code, which again does not release the NSMutableArray object:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSMutableArray *array = [[NSMutableArray alloc] init];
NSCalendarDate *now = [[NSCalendarDate alloc] init];

for (int i=0; i < 3; i++) {
    LotteryEntry *newEntry = [[LotteryEntry alloc] init];
    NSCalendarDate *iweeksFromNow = [now dateByAddingYears:0
                                                    months:0
                                                      days:(i*7)
                                                     hours:0
                                                   minutes:0 
                                                   seconds:0];
    [newEntry setEntryDate:iweeksFromNow];
    [array addObject:newEntry];
    [newEntry release];
}

[now release];

for (LotteryEntry *entry in array) {
    NSLog(@"%@", entry);
}


[pool drain];
return 0;

This time there was no leak reported. Am I missing something obvious?

+6  A: 

I don't think you are—the static analyzer's just missing it. array does end with a retain count of 1; if the line were

 NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];

then the enclosing autorelease pool would take care of it, but as it stands the array's definitely still leaking.

Noah Witherspoon
Or just `[NSMutableArray array]`.
Adrian
A: 

I've asked this on the cfe-dev list and the answer is analysis in loops is halted at a given threshold (only 2 loop iterations are walked through).

If you change your exit condition (for (int i=0; i < 2; i++)) the static analyzer will signal the leak.

diciu