(Mac OS X 10.6.8, Xcode 4.0.2, no GC)

I believe the following paragraph in the "Using Autorelease Pools" section of 
the "Memory Management Programming Guide" is wrong, or misleading:

"This behavior has implications for exceptional conditions. If an exception 
occurs, and the thread suddenly transfers out of the current context, the pool 
associated with that context is drained. However, if that pool is not the top 
pool on the thread’s stack, all the pools above the drained pool are also 
drained (releasing all their objects in the process). The top autorelease pool 
on the thread’s stack then becomes the pool previously underneath the drained 
pool associated with the exceptional condition. Because of this behavior, 
exception handlers do not need to release objects that were sent autorelease. 
Neither is it necessary or even desirable for an exception handler to send 
release to its autorelease pool, unless the handler is re-raising the 
exception."

In the following test program, if you leave the #define LEAK uncommented, the 
program leaks. Why? Is the above paragraph just wrong? Or am I missing 
something?

- lc


#import <Foundation/Foundation.h>

#import <malloc/malloc.h>

size_t heapSize()
{
    malloc_statistics_t stats;
    stats.size_in_use = 0;
    malloc_zone_statistics(malloc_default_zone(), &stats);
    return stats.size_in_use;
}

void allocAndRaise()
{
    [[[NSString alloc] initWithString:@"foo bar and zot"] autorelease];
    [NSException raise:@"foo" format:@"bar"];
}

//#define LEAK

void foo()
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    NS_DURING {
        allocAndRaise();
    } NS_HANDLER {
#ifdef LEAK
        [localException raise];
#else
        [localException retain];        // I don't think this workaround should 
be necessary, but it is
        [pool release];
        [[localException autorelease] raise];
#endif
    } NS_ENDHANDLER
    [pool release];
}

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [NSAutoreleasePool new];
    const unsigned kRepeatCount = 20*1000;
    unsigned i;
    for (i = 0; i < kRepeatCount; i++) {
        NSAutoreleasePool *pool = [NSAutoreleasePool new];
        NS_DURING {
            foo();
        } NS_HANDLER {
        } NS_ENDHANDLER
        [pool release];
        if (i && (i % 1000 == 0))
            printf("Iteration %5u heap %zu\n", i, heapSize());
    }
    [pool release];
    return 0;
}


Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to