Re: Analyser reports memory leak… where?
Re: Analyser reports memory leak… where?
- Subject: Re: Analyser reports memory leak… where?
- From: Aaron Montgomery <email@hidden>
- Date: Thu, 12 Sep 2013 08:19:22 -0700
I've been trying to reproduce this problem, but haven't been able to get the warning on a minimal example. However, I noticed something unusual trying to build a minimal example to play with. Here's a stripped down example (Xcode 4.6.3):
#import <Foundation/Foundation.h>
@interface MWObject : NSObject
@property (nonatomic, strong) NSObject* object;
- (NSObject*)newObject;
@end
@implementation MWObject
@synthesize object=_object;
- (void)dealloc
{
[super dealloc];
[_object release];
}
- (NSObject*)newObject
{
return [[NSObject alloc] init];
}
- (void)setObject:(NSObject *)object
{
[_object release];
_object = [object retain];//3
}
- (NSObject*)object
{
NSObject* theObject = [self newObject];
[self setObject:theObject];//2
[theObject release];//1
return _object;
}
@end
Version 0: as above and we do not get a warning (I believe the memory management is correct even if the semantics may be a little odd).
Version 1: Comment out line 1 and we do not get a warning (I would have suspected a leak of the theObject).
Version 2: Comment out lines 1 and 2 and we now get a warning (expected).
Version 3: Comment out lines 1 and 3 and we now get a warning (expected).
So somehow the retain call in the "setObject:" method is causing the release call in the "object" method to be ignored. As long as the compiler sees the retain on line 3, the inclusion or exclusion of the release on line 1 doesn't seem to matter. Something is pretty clearly confused because Version 0 and Version 1 cannot both have correct memory management.
Aaron
On Sep 12, 2013, at 7:42 AM, Fritz Anderson <email@hidden> wrote:
> On 12 Sep 2013, at 4:35 AM, Graham Cox <email@hidden> wrote:
>
>> Here's some code for which the Analyser reports "potential leak of an object stored into 'eventTypes'". I don't see it.
>>
>> I didn't write this code, so I'm reluctant to change it even though I would have written it a bit differently. mEventTypes is an ivar.
>>
>> - (void)setEventTypes:(NSDictionary*)eventTypes
>> {
>> if (eventTypes != mEventTypes)
>> {
>> [mEventTypes release];
>> mEventTypes = [eventTypes retain];
>> }
>> InitializePrefsForEventTypeNames();
>> }
>>
>> - (NSDictionary*)eventTypes
>> {
>> if (mEventTypes == nil)
>> {
>> [self loadNib];
>>
>> NSDictionary* eventTypes = [self newEventTypes];
>> [self setEventTypes:eventTypes];
>> [eventTypes release];
>> }
>> return mEventTypes; //<----- analyser complains here
>> }
>>
>> - (NSDictionary*)newEventTypes
>> {
>> //[code deleted that presets contents of 'eventTypes']
>>
>> // Method name begins with "new"; clients are responsible for releasing.
>> return [[NSDictionary alloc] initWithDictionary:eventTypes];
>> }
>
> I tried a Foundation-tool project that included a class with the methods you show, dummying the methods and functions not shown as empty void-returning-void, and dictionary data as one string-keying-string. ARC off.
>
> Running this through a later version of clang showed no analyzer errors. I think it's a bug in the version of clang you're using. Or: clang does cross-function checks to one degree or another. Can you make a minimal example, and add the code you omitted here to see what makes the analyzer unhappy?
>
> I assume you expanded the note and examined the code path on which the compiler saw a potential problem?
>
> — F
>
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden