开发者

Weird "EXC_BAD_ACCESS" error

I'm trying to make a simple binary-adding app. Here's the two main methods that I use. You can assume that anything I don't declare in the code has been declared in the header file:

-(IBAction)valuesChanged
{
    if ((![input1.text isEqualToString:@""]) && (![input2.text isEqualToString:@""]))
    {
        if (bitRange.selectedSegmentIndex == 0) {flowLimit = 8;}
        else if (bitRange.selectedSegmentIndex == 1) {flowLimit = 16;}
        else {flowLimit = 32;}

        NSMutableArray* bin1 = [[NSMutableArray alloc] initWithCapacity:32];
        NSMutableArray* bin2 = [[NSMutableArray alloc] initWithCapacity:32];
        NSMutableArray* resBin = [[NSMutableArray alloc] initWithCapacity:32];

        input1Decimal = [input1.text intValue];
        input2Decimal = [input2.text intValue];

        int decimalDummy = input1Decimal;
        while (decimalDummy > 0) 
        {
            if (decimalDummy == 1) 
            {
                [bin1 addObject:[NSNumber numberWithInt:1]];
                decimalDummy--;
            }
            else 
            {
                [bin1 addObject:[NSNumber numberWithInt:(decimalDummy % 2)]];
                decimalDummy = decimalDummy/2;
            }
        }

        decimalDummy = input2Decimal;
        while (decimalDummy > 0) 
        {
            if (decimalDummy == 1) 
            {
                [bin2 addObject:[NSNumber numberWithInt:1]];
                decimalDummy--;
            }
            else 
            {
                [bin2 addObject:[NSNumber numberWithInt:(decimalDummy % 2)]];
                decimalDummy = decimalDummy/2;
            }
        }

        while ([bin1 count] < flowLimit) {[bin1 addObject:[NSNumber numberWithInt:0]];}
        while ([bin2 count] < flowLimit) {[bin2 addObject:[NSNumber numberWithInt:0]];}

        resBin = [self addBinary:bin1 toBinary:bin2];

        NSString* string1 = @"";
        NSString* string2 = @"";
        NSString* string3 = @"";
        for (int i = 0; i < flowLimit; i++) 
        {
            string1 = [[NSString stringWithFormat:@"%@",[bin1 objectAtIndex:i]] stringByAppendingString:string1];
            string2 = [[NSString stringWithFormat:@"%@",[bin2 objectAtIndex:i]] stringByAppendingString:string2];
            string3 = [[NSString strin开发者_运维百科gWithFormat:@"%@",[resBin objectAtIndex:i]] stringByAppendingString:string3];
        }
        [output1 setText:string1];
        [output2 setText:string2];
        [binResult setText:string3];

        [bin1 release];
        [bin2 release];
        [resBin release];
    }
}

-(NSMutableArray*)addBinary:(NSMutableArray*)binary1 toBinary:(NSMutableArray*)binary2
{
    BOOL carry = NO;
    NSMutableArray* result = [NSMutableArray arrayWithCapacity:32];
    for (int i = 0; i < flowLimit; i++) 
    {
        if (([[binary1 objectAtIndex:i] intValue] == 0) && ([[binary2 objectAtIndex:i] intValue] == 0)) 
        {
            if (carry) 
            {
                [result addObject:[NSNumber numberWithInt:1]];
            }
            else {[result addObject:[NSNumber numberWithInt:0]];}
        }
        else if (([[binary1 objectAtIndex:i] intValue] == 1) && ([[binary2 objectAtIndex:i] intValue] == 0)) 
        {
            if (carry) 
            {
                [result addObject:[NSNumber numberWithInt:0]];
                carry = YES;
            }
            else {[result addObject:[NSNumber numberWithInt:1]];}
        }
        else if (([[binary1 objectAtIndex:i] intValue] == 0) && ([[binary2 objectAtIndex:i] intValue] == 1)) 
        {
            if (carry) 
            {
                [result addObject:[NSNumber numberWithInt:0]];
                carry = YES;
            }
            else {[result addObject:[NSNumber numberWithInt:1]];}
        }
        else
        {
            if (carry) 
            {
                [result addObject:[NSNumber numberWithInt:1]];
                carry = YES;
            }
            else 
            {
                [result addObject:[NSNumber numberWithInt:0]];
                carry = YES;
            }

        }
        carry = NO;
    }
    return result;
}

The code runs fine in the debugger, but somewhere after these methods are run, I get an "EXC_BAD_ACCESS" error. Anyone know why this is happening?


Instead of removing all the [X release] messages, try changing this:

NSMutableArray* bin1 = [[NSMutableArray alloc] initWithCapacity:32];
NSMutableArray* bin2 = [[NSMutableArray alloc] initWithCapacity:32];
NSMutableArray* resBin = [[NSMutableArray alloc] initWithCapacity:32];

To this:

NSMutableArray* bin1 = [NSMutableArray array];
NSMutableArray* bin2 = [NSMutableArray array];
NSMutableArray* resBin = [NSMutableArray array];

Named initializers are autoreleased by default, but when you explicitely call alloc and initialize the return value of alloc, you must release it or it will leak.


Another good debugging tip:

Set NSZombieEnabled, malloc stack logging, and guard malloc in the debugger. Then, when your App crashes, type this in the gdb comsole:

(gdb) info malloc-history 0x543216

Replace 0x543216 with the address of the object that the stack trace says caused the crash,and it will give you a much more useful stack trace and it should highlight the exact line that is causing the problem.

Check out this article for more info on NSZombieEnabled.

This one for MallocStackLogging info

More info on guard malloc here


After rereading the code, the only problem I can see is here:

resBin = [self addBinary:bin1 toBinary:bin2];
[resBin release];

Your releasing something without increasing the retain count first and since it has already been autoreleased by the second method, you get the EXC_BAD_ACCESS. Either remove the [resBin release]; or do this:

NSMutableArray *resBin = [[NSMutableArray alloc] initWithArray:[self addBinary:bin1 toBinary:bin2]];

Then you can safely call [resBin release];.


Try removing all

[something release]

of those mutable arrays. Then see if that fixes the problem. If you know the cause you can come up with the solution. If that is your cause, check the code for any other usage of any data from those arrays.

Update:

you can also try to add the following code

[something autorelease];

for each of those arrays.


I think your problem is mos likely in the second method

-(NSMutableArray*)addBinary:(NSMutableArray*)binary1 toBinary:(NSMutableArray*)binary2

You are creating the result array

NSMutableArray* result = [NSMutableArray arrayWithCapacity:32];

Wich creates an autoreleased instance of a NSArray wich then you return and I assume you make use of it somewhere else in your code, but since its autoreleased when you try to access it is most likely to had already been released by the system.

I would recommend that you retain the result when you call the method. For example

binary1_plus_binary2 = [[binaryObject addBinary:binary1 toBinary:binary2] retain];

And when your done using binary1_plus_binary2 you release it.

==================

EDIT

resBin is being released but that variable is already released since its the result from addBinary method, don't release that one, only relese the other two, the ones you initiated with alloc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜