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 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;
}
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:To this:
Named initializers are autoreleased by default, but when you explicitely call
allocand 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:
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:
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:Then you can safely call
[resBin release];.