Hi all,

I've run into a funny crash when using -[NSString stringWithCString:encoding:]. The code in question runs in the iPhone Simulator. I haven't found anything on the web about this, but I found out some things by experimenting. I have a workaround, but I'm curious what's going on. I'd be very interested to hear your thoughts on this - apologies for the lengthy post!

This is the relevant piece of code - I'm sorry I can't post it in full (NDA prohibits):

        nTags = 15;
unsigned long metadataTags[] = { /* fifteen tags defined in some library */ };

NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] initWithCapacity:nTags];
        
        for (NSUInteger i = 0; i < nTags; i++) {
                unsigned long pcLength = 0;
if (getLengthOfMetaData(fileHandle, metadataTags[i], 0, &pcLength) ! = 0) continue;
                
                // pcLength is now the required buffer size.
                // Fill the buffer with metadata (and make room for a \0)
                unsigned char *pBuffer = malloc(pcLength + 1);
                
if (getMetadata(fileHandle, metadataTags[i], pBuffer, pcLength) == 0) {
                        pBuffer[pcLength] = '\0';
                        
NSString *key = [[NSString alloc] initWithFormat:@"%d", metadataTags [i]]; NSString *contents = [[NSString alloc] initWithCString:(const char *)pBuffer encoding:NSASCIIStringEncoding];
                        
                        [tempDict setValue:contents forKey:key];
                        
                        [key release];
                        [contents release];
                }
                
                free(pBuffer);
        }
        
        _metaData = [[NSDictionary alloc] initWithDictionary:tempDict];
        [tempDict release];

The code runs as part of an -init method, and sets the _metaData instance variable (it's an NSDictionary *) of the class in question. Most of the time, but not always, the last line ([tempDict release]) crashes with the following stack backtrace (MyApp, MyFile, etc. do have better names than that):

        Exception Type:  EXC_BAD_ACCESS (SIGBUS)
        Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000000000005
        Crashed Thread:  0
        
        Application Specific Information:
        iPhone Simulator 3.1 (139.1), iPhone OS 3.0 (7A341)
        
        Thread 0 Crashed:
        0   CoreFoundation                      0x302042c0 CFRelease + 96
1 CoreFoundation 0x30227249 __CFDictionaryDeallocate + 281
        2   CoreFoundation                      0x30204421 _CFRelease + 241
3 MyApp 0x00004ca0 -[MyFile getMetaDataFromFileHandle:] + 859 (MyFile.m:247) 4 MyApp 0x000042fd -[MyFile initWithPath:] + 382 (MyFile.m:62) 5 MyApp 0x000026b4 -[MyAppDelegate applicationDidFinishLaunching:] + 407 (MyAppDelegate.m:68) 6 UIKit 0x308f8ac3 -[UIApplication _performInitializationWithURL:sourceBundleID:] + 500 7 UIKit 0x30901bf5 -[UIApplication _runWithURL:sourceBundleID:] + 594 8 UIKit 0x308fef33 -[UIApplication handleEvent:withNewEvent:] + 1532 9 UIKit 0x308fad82 -[UIApplication sendEvent:] + 71 10 UIKit 0x309013e1 _UIApplicationHandleEvent + 4865 11 GraphicsServices 0x32046375 PurpleEventCallback + 1533 12 CoreFoundation 0x30245560 CFRunLoopRunSpecific + 3888
        13  CoreFoundation                      0x30244628 CFRunLoopRunInMode + 
88
14 UIKit 0x308f930d -[UIApplication _run] + 611
        15  UIKit                               0x309021ee UIApplicationMain + 
1157
        16  MyApp                               0x00002324 main + 102 
(main.m:13)
        17  MyApp                               0x00002292 start + 54

Here's what I found:

1. If I use -[NSString initWithUTF8String:], the crash doesn't happen.
2. If I allocate pBuffer only once, outside of the loop, the crash doesn't happen. 3. If I print out the memory ranges that pBuffer occupies, it seems that the crash happens when one allocation of pBuffer overlaps another one. If they start at the same address, it's no problem, but if they start at different addresses and overlap, it's a problem. This is why the app doesn't always crash: if the memory ranges don't happen to overlap, all is well.

So, I'm curious about how -[NSString initWithCString:encoding:] works. According to the documentation, it returns "An NSString object initialized using the characters from nullTerminatedCString." Does that mean it doesn't copy the bytes? Then what does it do? -[NSString initWithUTF8String] explicitly states that it returns "An NSString object initialized by copying the bytes from bytes."

Any insight is greatly appreciated!

Many thanks,
Hank

_______________________________________________

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