Mac NSArray count error

Richard Birkett

macrumors member
Original poster
Aug 21, 2011
30
0
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
 

robvas

macrumors 68040
Mar 29, 2009
3,044
511
USA
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.
 
Last edited:
Comment

JoshDC

macrumors regular
Apr 8, 2009
115
0
[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])
 
Comment

gnasher729

macrumors P6
Nov 25, 2005
16,819
3,628
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
Just saying:

Code:
for (NSInteger j = [variableFactors count] - 1; j >= 0; --j)
    if ([(RBMVariableFactor *)[variableFactors objectAtIndex:j] exponent] == 0)
        [variableFactors removeObjectAtIndex:j];
 
Comment
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.