2011-09-25 34 views
1

我試圖做一個簡單的二進制添加應用程序。以下是我使用的兩種主要方法。你可以假設任何事情我不代碼聲明在頭文件中已經聲明:奇怪的「EXC_BAD_ACCESS」錯誤

-(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」錯誤。任何人都知道這是爲什麼發生?

回答

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並初始化返回值的分配,你必須釋放它或它會泄漏。


另外一個很好的調試提示:

設置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];

+0

我承認,這是一個比我更好的主意。 –

+0

+1這是正確的答案。你已經在你的方法開始時分配了resBin,但隨後通過調用'[self addBinary:toBinary]'將它重新分配給一個自動釋放的可變數組,因此釋放resBin導致崩潰(並導致它崩潰)。 – Rog

+0

實際上,使用'NSMutableArray * bin1 = [NSMutableArray array];'使用'withCapacity'版本可以獲得很少或沒有什麼東西。 – zaph

0

嘗試刪除所有

[something release] 
那些可變陣列

。然後看看是否解決了這個問題。如果你知道原因,你可以拿出解決方案。如果這是您的原因,請檢查代碼是否存在其他數據的其他用法。

更新:

你也可以嘗試添加以下代碼

[something autorelease]; 

爲每個陣列。

+0

好的,我刪除了版本,代碼現在正在工作,甚至使用了泄漏性能工具,而且我沒有發現任何泄漏。還有什麼我需要擔心的,還是完全解決了問題? – RaysonK

+0

這應該可以解決問題。我討厭這個客觀的c。 gl –

+0

太棒了,謝謝! – RaysonK

0

我認爲你的問題很可能在第二個方法MOS

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

您創建的結果數組

NSMutableArray * result = [NSMutableArray arrayWithCapacity:32];

至極創建的NSArray的自動釋放實例至極然後你回來,我想你利用它別的地方在你的代碼,但由於它的自動釋放,當您嘗試訪問它是最有可能已被釋放由系統。

我建議你保留的結果,當你調用該方法。例如

binary1_plus_binary2 = [[binaryObject addBinary:binary1 toBinary:binary2]保留];

當您使用binary1_plus_binary2你釋放它完成。

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

EDIT

resBin被釋放,但因爲它的從addBinary方法,別結果是變量已經釋放不會釋放那個,只會讓其他兩個,你用alloc啓動的那兩個。

+0

+1先生,良好的捕獲。 – chown