奇怪的“EXC_BAD_ACCESS”错误

时间:2011-09-25 04:26:46

标签: objective-c xcode

我正在尝试制作一个简单的二进制添加应用。这是我使用的两种主要方法。您可以假设我在代码中未声明的任何内容都已在头文件中声明:

-(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 stringWithFormat:@"%@",[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;
}

代码在调试器中运行良好,但在运行这些方法后的某个地方,我收到“EXC_BAD_ACCESS”错误。任何人都知道为什么会这样吗?

3 个答案:

答案 0 :(得分:1)

请尝试更改此内容,而不是删除所有[X release]条消息:

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

对此:

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

默认情况下,命名初始值设定项是自动释放的,但是当你明确地调用alloc并初始化alloc的返回值时,你必须释放它或者它会泄漏。


另一个好的调试技巧:

在调试器中设置NSZombieEnabled,malloc堆栈日志记录和保护malloc。然后,当您的应用程序崩溃时,请在gdb comsole中输入:

(gdb) info malloc-history 0x543216

将0x543216替换为堆栈跟踪所导致崩溃的对象的地址,它将为您提供更有用的堆栈跟踪,并且应突出显示导致问题的确切行。

Check out this article for more info on NSZombieEnabled

This one for MallocStackLogging info

More info on guard malloc here


重新阅读代码之后,我能看到的唯一问题是:

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

你首先发布的东西没有增加保留计数,因为它已经被第二种方法自动释放,你得到EXC_BAD_ACCESS。删除[resBin release];或执行此操作:

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

然后您可以安全地拨打[resBin release];

答案 1 :(得分:0)

尝试删除所有

[something release]

那些可变数组。然后看看是否能解决问题。如果你知道原因,你可以提出解决方案。如果这是您的原因,请检查代码以获取这些阵列中任何数据的任何其他用法。

更新

您还可以尝试添加以下代码

[something autorelease];

对于每个阵列。

答案 2 :(得分:0)

我认为你的问题很可能出现在第二种方法中

  

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

您正在创建结果数组

  

NSMutableArray * result = [NSMutableArray arrayWithCapacity:32];

Wich创建一个NSArray的自动释放实例,然后你返回,我假设你在代码中的其他地方使用它,但是因为当你试图访问它时它自动释放它很可能已经被系统释放了

我建议您在调用方法时保留结果。例如

  

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

当您使用binary1_plus_binary2完成后,您将其释放。

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

修改

resBin正在发布但是该变量已经被释放,因为它来自addBinary方法的结果,不释放那个,只释放其他两个,你用alloc启动的那个。