FROM : Greg Titus
DATE : Mon Feb 04 16:39:53 2008
On Feb 3, 2008, at 5:57 PM, John Engelhart wrote:
> int main(int argc, char *argv[]) {
> GCTest *gcConstTitle = NULL, *gcUTF8Title = NULL;
>
> gcConstTitle = [[GCTest alloc] init];
> gcUTF8Title = [[GCTest alloc] init];
>
> [gcConstTitle setTitle:"Hello, world!"];
> [gcUTF8Title setTitle:[[NSString stringWithUTF8String:"Hello, world
> \xC2\xA1"] UTF8String]];
>
> [[NSGarbageCollector defaultCollector] collectExhaustively];
> NSLog(@"GC test");
>
> printf("gcConstTitle title: %p = '%s'\n", [gcConstTitle title],
> [gcConstTitle title]);
> printf("gcUTF8Title title: %p = '%s'\n", [gcUTF8Title title],
> [gcUTF8Title title]);
>
> return(0);
> }
> The problem is with the pointer returned by UTF8String. From
> NSString.h:
>
> - (const char *)UTF8String; // Convenience to return null-terminated
> UTF8 representation
>
> I strongly suspect the pointer that UTF8String returns is a pointer
> to an allocation from the garbage collector. In fact, by changing
> the 'title' ivar to include __strong 'solves' the problem.
I'd just like to comment quickly that in Tiger and earlier OS X
releases without GC, that your code here would be just as broken. The -
UTF8String method has always returned "autoreleased memory", that is,
a pointer to a UTF8 string that is only being held by an autoreleased
object. So once the containing autorelease pool was dealloced, so
would the UTF8 string representation, and you'd have a bad pointer to
unallocated memory in your object.
In fact, unlike in the GC world, there was no way to actually keep
that memory around longer. There was no way to tell it that you wanted
a __strong reference. If you wanted to keep a pointer to a UTF8
representation you had to do your own malloc() and make your own copy.
And that is why this isn't a problem. The new GC implementation
doesn't make anything a bug that was legal before - it was just as
much of a crasher before GC as it is after GC.
Hope this helps,
- Greg
DATE : Mon Feb 04 16:39:53 2008
On Feb 3, 2008, at 5:57 PM, John Engelhart wrote:
> int main(int argc, char *argv[]) {
> GCTest *gcConstTitle = NULL, *gcUTF8Title = NULL;
>
> gcConstTitle = [[GCTest alloc] init];
> gcUTF8Title = [[GCTest alloc] init];
>
> [gcConstTitle setTitle:"Hello, world!"];
> [gcUTF8Title setTitle:[[NSString stringWithUTF8String:"Hello, world
> \xC2\xA1"] UTF8String]];
>
> [[NSGarbageCollector defaultCollector] collectExhaustively];
> NSLog(@"GC test");
>
> printf("gcConstTitle title: %p = '%s'\n", [gcConstTitle title],
> [gcConstTitle title]);
> printf("gcUTF8Title title: %p = '%s'\n", [gcUTF8Title title],
> [gcUTF8Title title]);
>
> return(0);
> }
> The problem is with the pointer returned by UTF8String. From
> NSString.h:
>
> - (const char *)UTF8String; // Convenience to return null-terminated
> UTF8 representation
>
> I strongly suspect the pointer that UTF8String returns is a pointer
> to an allocation from the garbage collector. In fact, by changing
> the 'title' ivar to include __strong 'solves' the problem.
I'd just like to comment quickly that in Tiger and earlier OS X
releases without GC, that your code here would be just as broken. The -
UTF8String method has always returned "autoreleased memory", that is,
a pointer to a UTF8 string that is only being held by an autoreleased
object. So once the containing autorelease pool was dealloced, so
would the UTF8 string representation, and you'd have a bad pointer to
unallocated memory in your object.
In fact, unlike in the GC world, there was no way to actually keep
that memory around longer. There was no way to tell it that you wanted
a __strong reference. If you wanted to keep a pointer to a UTF8
representation you had to do your own malloc() and make your own copy.
And that is why this isn't a problem. The new GC implementation
doesn't make anything a bug that was legal before - it was just as
much of a crasher before GC as it is after GC.
Hope this helps,
- Greg






Cocoa mail archive

