Search code examples
iosnsstringexc-bad-accesscstring

EXC_BAD_ACCESS error when using NSString getCString


I'm trying to parse some HTML. I use stringWithContentsOfURL to get the HTML. I attempt to load this into a character array so I can parse it, but I crash with the EXC_BAD_ACCESS error when getCString is called. Here is the relavent code:

- (void)parseStoryWithURL:(NSURL *)storyURL
{
    _paragraphs = [[NSMutableArray alloc] initWithCapacity:10];
    _read = NO;

    NSError* error = nil;
    NSString* originalFeed = [NSString stringWithContentsOfURL:storyURL encoding:NSUTF8StringEncoding error:&error];

    _i = originalFeed.length;
   char* entireFeed = malloc(_i*sizeof(char));
   char* current = entireFeed;
   char* lagger;
   char* recentChars = malloc(7);
   BOOL collectRecent = NO;
   BOOL paragraphStarted = NO;
   BOOL paragraphEnded = NO;
   int recentIndex = 0;
   int paragraphSize = 0;

   NSLog(@"original Feed: %@", originalFeed);


   _read = [originalFeed getCString:*entireFeed maxLength:_i encoding:NSUTF8StringEncoding];

I've also tried this passing the 'current' pointer to getCString but it behaves the same. From what I've read this error is typically thrown when you try to read from deallocated memory. I'm programming for iOS 5 with memory management. The line before that I print the HTML to the log and everything is fine. Help would be appreciated. I need to get past this error so I can test/debug my HTML parsing algorithms.

PS: If someone with enough reputation is allowed to, please add "getCString" as a tag. Apparently no one uses this function :(


Solution

  • There are several issues with your code - you're passing the wrong pointers and not reserving enough space. Probably the easiest is to use UTF8String instead:

    char *entireFeed = strdup([originalFeed UTF8String]);
    

    At the end you'll have to free the string with free(entireFeed) though. If you don't modify it you can use

    const char *entireFeed = [originalFeed UTF8String];
    

    directly.

    If you want to use getCString, you'll need to determine the length first - which has to include the termination character as well as extra space for encoded characters, so something like:

    NSUInteger len = [originalFeed lengthOfBytesUsingEncoding: NSUTF8StringEncoding] + 1;
    char entireFeed[len];
    [originalFeed getCString:entireFeed maxLength:len encoding:NSUTF8StringEncoding];