NSArray count error

Discussion in 'Mac Programming' started by Richard Birkett, Jan 14, 2012.

  1. macrumors member

    Joined:
    Aug 21, 2011
    #1
    Hello,
    I have this code:

    Code:
    if ([variableFactors count] >= 1) {
    		short j = 0;
    		bool shouldRun = true;
    		while (shouldRun) {
    			if ([(RBMVariableFactor *)[variableFactors objectAtIndex:j] exponent] == 0) {
    					//if factor is empty then remove
    				[variableFactors removeObjectAtIndex:j];
    			}else{
    				j++;
    			}
    			shouldRun = (j <= ([variableFactors count] - 1));
    		}
    	}
    When I have variableFactors with 1 object that satisfies the second if statement, it gets removed before the shouldRun line.
    At this point I check with breakpoints that j is 0, variableFactors says '0 objects', I set a breakpoint for after shouldRun is reassigned and it is still true!!! The while loops again and the code crashes because I'm accessing an empty array.
    Please help...

    Richard
     
  2. robvas, Jan 14, 2012
    Last edited: Jan 14, 2012

    macrumors 68000

    Joined:
    Mar 29, 2009
    Location:
    USA
    #2
    I'm getting a compile error on the line ([(RBMVariableFactor....

    Your last line where you do 'shouldRun = ....' is the problem.

    Look at this program:

    Code:
        NSMutableArray *variableFactors = [NSMutableArray arrayWithObjects:@"Foo", nil];
            
            NSLog(@"Count is %lu", [variableFactors count]);
            [variableFactors removeObjectAtIndex:0];
            
            NSLog(@"Count is %lu after removing object at index 0", [variableFactors count]);
    
            NSLog(@"Count - 1 is %lu", [variableFactors count] - 1);
            
    
    It outputs:
    Code:
    MBHelp[1003:903] Count is 1
    MBHelp[1003:903] Count is 0 after removing object at index 0
    MBHelp[1003:903] Count - 1 is 18446744073709551615
    
    The 'count' method returns an unsigned int - which can't be negative, which is probably what you were expecting to compare j to.
     
  3. macrumors regular

    Joined:
    Apr 8, 2009
    #3
    [NSArray count] returns an unsigned integer. Taking 1 from 0 will cause it to wrap around to its maximum value (NSUIntegerMax), so this:

    Code:
    NSLog(@"%d", 0 <= ([[NSArray array] count] - 1));
    
    Will print 1, as it evaluates to 0 <= NSUIntegerMax.

    You can either cast the value to a signed integer:

    Code:
    j <= (NSInteger)([[NSArray array] count] - 1)
    Or use a different inequality:

    Code:
    j < [[NSArray array] count]
    I'd suggest the second option.

    As a side point, you'd usually see people checking for a non-zero count like this:

    Code:
    if ([variableFactors count] > 0)
    Or more succinctly as:

    Code:
    if ([variableFactors count])
     
  4. thread starter macrumors member

    Joined:
    Aug 21, 2011
    #4
    Thank you both so much, I removed the = and -1, now it works perfectly.
    :)
     
  5. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #5
    Just saying:

    Code:
    for (NSInteger j = [variableFactors count] - 1; j >= 0; --j)
        if ([(RBMVariableFactor *)[variableFactors objectAtIndex:j] exponent] == 0)
            [variableFactors removeObjectAtIndex:j];
    
     

Share This Page