discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GNUstep and valgrind


From: Fred Kiefer
Subject: Re: GNUstep and valgrind
Date: Fri, 16 Mar 2018 18:58:32 +0100


> Am 16.03.2018 um 18:39 schrieb Fred Kiefer <address@hidden>:
> 
> 
> 
>> Am 16.03.2018 um 17:53 schrieb Richard Frith-Macdonald <address@hidden>:
>> 
>> 
>> 
>>> On 16 Mar 2018, at 15:44, Fred Kiefer <address@hidden> wrote:
>>> 
>>> 
>>> 
>>>> Am 16.03.2018 um 16:32 schrieb Richard Frith-Macdonald <address@hidden>:
>>>> 
>>>> 
>>>> 
>>>>> On 16 Mar 2018, at 15:18, amon <address@hidden> wrote:
>>>>> 
>>>>> 
>>>>>        [arglist release];
>>>>> arglist = [[[NSMutableString stringWithCString: [cmdline cString]]
>>>>>           componentsSeparatedByString: DELIM] retain];
>>>>> 
>>>>> This happens inside an init. arglist is release by the dealloc
>>>>> method. However, NSMutableString insists on making it autoreleased.
>>>>> I want to make it not do that. 
>>>> 
>>>> Portable GNUstep code would look like this:
>>>> 
>>>> CREATE_AUTORELEASE_POOL(pool);
>>>> ASSIGN(arglist, [[[NSMutableString stringWithCString: [cmdline cString]] 
>>>> componentsSeparatedByString: DELIM]);
>>>> DESTROY(pool);
>>>> 
>>>> with no wasted/leaked memory.
>>> 
>>> I have to disagree. This will get rid of the intermediate NSMutableString 
>>> but later on when the surrounding Foo object gets released the arglist ivar 
>>> will get released as well, but the component strings in that array will 
>>> still remain in what ever autorelease pool is active at that time and will 
>>> only get freed when that pool is cleaned up.
>> 
>> That's (almost always) wrong.  Releasing a container does not put its 
>> contents into an autorelease pool, it releases them all. so the components 
>> get released/deallocated at the point when the array is deallocated.
>> 
>> Of course you can never guarantee that a class will behave normally (if you 
>> don't have access to its source code), but generally when an object is 
>> deallocated it releases all its instance variables.
>> 
>> In this instance I think it's fair to assume we are talking about the 
>> GNUstep NSMutableString class generating components in a GNUstep NSArray, so 
>> we know that we don't have some perverse implementation and the above 
>> three-line solution is all that's needed to ensure no leaked objects.
>> 
>> However, I agree that if someone had for instance re-implemented 
>> -componentsSeparatedByString: in a category of NSMutableString, and their 
>> re-implementation had created an NSArray subclass which, on deallocation, 
>> would put the array contents into an autorelease pool rather than releasing 
>> them, then you could get the situation you describe where the components 
>> would be placed in a pool at the point when the array ivar is released.
> 
> Are we talking about this method:
> 
> - (NSArray*) componentsSeparatedByString: (NSString*)separator
> {
>  NSRange      search;
>  NSRange      complete;
>  NSRange      found;
>  NSMutableArray *array = [NSMutableArray array];
> 
>  search = NSMakeRange (0, [self length]);
>  complete = search;
>  found = [self rangeOfString: separator
>                      options: 0
>                        range: search
>                       locale: nil];
>  while (found.length != 0)
>    {
>      NSRange current;
> 
>      current = NSMakeRange (search.location,
>       found.location - search.location);
>      [array addObject: [self substringWithRange: current]];
> 
>      search = NSMakeRange (found.location + found.length,
>       complete.length - found.location - found.length);
>      found = [self rangeOfString: separator
>                         options: 0
>                           range: search
>                           locale: nil];
>    }
>  // Add the last search string range
>  [array addObject: [self substringWithRange: search]];
> 
>  // FIXME: Need to make mutable array into non-mutable array?
>  return array;
> }
> 
> Here the elements in the array get generated via the method 
> substringWithRange: and this will return autoreleased objects. Which should 
> lead to about the scenario I was talking about. And I thing this is the big 
> issue for the original poster. Even if he manages to keep all the objects 
> that his code generates properly non-autoreleased, there will be some 
> internal objects that may be created autoreleased by library methods.

I think that now I see the flaw in my argument. I was under the impression that 
an autorelease pool will only release contained objects if they have a 
reference count of one. But that is nonsense. The autorelease pool will release 
all contained objects and as usual the ones where the reference count drops to 
zero will be deallocated. The autorelease pool itself doesn’t care about the 
reference count. That way your example was correct, with the autorelease pool 
around the object creation they will only be retained by the array and go away 
when that is deallocated.

Sorry for the confusion.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]