• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
-[NSString stringWithCString:encoding:] memory management question
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

-[NSString stringWithCString:encoding:] memory management question


  • Subject: -[NSString stringWithCString:encoding:] memory management question
  • From: "Hank Heijink (Mailinglists)" <email@hidden>
  • Date: Wed, 11 Nov 2009 14:58:58 -0500

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 (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


  • Follow-Ups:
    • Re: -[NSString stringWithCString:encoding:] memory management question
      • From: Jens Miltner <email@hidden>
    • Re: -[NSString stringWithCString:encoding:] memory management question
      • From: Jeremy Pereira <email@hidden>
    • Re: -[NSString stringWithCString:encoding:] memory management question
      • From: Greg Parker <email@hidden>
  • Prev by Date: Derived properties
  • Next by Date: Re: Derived properties
  • Previous by thread: Re: Derived properties
  • Next by thread: Re: -[NSString stringWithCString:encoding:] memory management question
  • Index(es):
    • Date
    • Thread