EXC_BAD_ACCESS in CFAttributedStringSetAttribute and NSNumber?

Posted by RichardR on Stack Overflow See other posts from Stack Overflow or by RichardR
Published on 2010-06-06T18:33:56Z Indexed on 2010/06/06 18:42 UTC
Read the original article Hit count: 521

Hi all,

I am getting an infuriating EXC_BAD_ACCESS error in an objective c app I am working on. Any help you could offer would be much appreciated. I have tried the normal debug methods for this error (turning on NSZombieEnabled, checking retain/release/autorelease to make sure I'm not trying to access a deallocated object, etc.) and it hasn't seemed to help.

Basically, the error always occurs in this function:

` void op_TJ(CGPDFScannerRef scanner, void *info) { PDFPage *self = info; CGPDFArrayRef array;

NSMutableString *tempString = [NSMutableString stringWithCapacity:1];
NSMutableArray *kernArray = [[NSMutableArray alloc] initWithCapacity:1];

if(!CGPDFScannerPopArray(scanner, &array)) {
    [kernArray release];
    return;
}

for(size_t n = 0; n < CGPDFArrayGetCount(array); n += 2)
{
    if(n >= CGPDFArrayGetCount(array))
        continue;

    CGPDFStringRef pdfString;

    // if we get a PDF string
    if (CGPDFArrayGetString(array, n, &pdfString))
    {
        //get the actual string
        const unsigned char *charstring = CGPDFStringGetBytePtr(pdfString);

        //add this string to our temp string
        [tempString appendString:[NSString stringWithCString:(const char*)charstring encoding:[self pageEncoding]]];
        //NSLog(@"string: %@", tempString);

        //get the space after this string
        CGPDFReal r = 0;
        if (n+1 < CGPDFArrayGetCount(array)) {
            CGPDFArrayGetNumber(array, n+1, &r);

            // multiply by the font size
            CGFloat k = r;
            k = -k/1000 * self.tmatrix.a * self.fontSize;


            CGFloat kKern = self.kern * self.tmatrix.a;
            k = k + kKern;

            // add the location and kern to the array
            NSNumber *tempKern = [NSNumber numberWithFloat:k];
            NSLog(@"tempKern address: %p", tempKern);
            [kernArray addObject:[NSArray arrayWithObjects:[NSNumber numberWithInt:[tempString length] - 1], tempKern, nil]];

        }
    }
}

// create an attribute string
CFMutableAttributedStringRef attString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 10);

CFAttributedStringReplaceString(attString, CFRangeMake(0, 0), (CFStringRef)tempString);

//apply overall kerning
NSNumber *tkern = [NSNumber numberWithFloat:self.kern * self.tmatrix.a * self.fontSize];
CFAttributedStringSetAttribute(attString, CFRangeMake(0, CFAttributedStringGetLength(attString)), kCTKernAttributeName, (CFNumberRef)tkern);

//apply individual kern attributes
for (NSArray *kernLoc in kernArray) {
    NSLog(@"kern location: %i, %i", [[kernLoc objectAtIndex:0] intValue],[[kernLoc objectAtIndex:1] floatValue]);
    CFAttributedStringSetAttribute(attString, CFRangeMake([[kernLoc objectAtIndex:0] intValue], 1), kCTKernAttributeName, (CFNumberRef)[kernLoc objectAtIndex:1]);
}

CFAttributedStringReplaceAttributedString([self cfAttString], CFRangeMake(CFAttributedStringGetLength([self cfAttString]), 0), attString);

//release
CFRelease(attString);
[kernArray release];

}

`

The program always crashes because of line

CFAttributedStringSetAttribute(attString, CFRangeMake([[kernLoc objectAtIndex:0] intValue], 1), kCTKernAttributeName, (CFNumberRef)[kernLoc objectAtIndex:1])

And it seems to depend on a few things:

  1. if [kernLoc objectAtIndex:1] refers to an [NSNumber numberWithFloat:k] where k = 0 (in other words, if k = 0 above where I populate kernArray) then the program crashes almost immediately

  2. If I comment out the line k = k + kKern, it takes longer for the program to crash, but does eventually (why would the crash depend on this value?)

  3. If I change the length of CFRangeMake from 1 to 0, it takes a lot longer for the program to crash, but still eventually does. (I don't think I am trying to access beyond the bounds of attString, but am I missing something?)

When it crashes, I get something similar to:

#0  0x942c7ed7 in objc_msgSend ()
#1  0x00000013 in ?? ()
#2  0x0285b827 in CFAttributedStringSetAttribute ()
#3  0x0000568f in op_TJ (scanner=0x472a590, info=0x4a32320) at /Users/Richard/Desktop/AppTest/PDFHighlight 2/PDFScannerOperators.m:251

Any ideas? It seems like somewhere along the way I am overwriting memory or trying to access memory that has been changed, but I have no idea. If there's anymore information I can provide, please let me know.

Thanks, Richard

© Stack Overflow or respective owner

Related posts about iphone

Related posts about objective-c