views:

74

answers:

4

I have a C array defined in my method as:

int c = 4;
int r = 5;
keysArray[c][r];

I have this for loop, which works, populating the keysArray as expected.

for (int row = 0; row < r; row++) {
    for (int column = 0; column < c; column++){
        keysArray[column][row] = [anotherArray objectAtIndex:0];
        NSLog(@"array1 %@",keysArray[column][row]);
        [anotherArray removeObjectAtIndex:0];
    }
}

Then in a for loop underneath, featuring exactly the same looping counter structure, when i try to NSLog the array, it gives an EXC_BAD_ACCESS.

for (int row = 0; row < r; row++){
    for (int column = 0; column < c; column++) {            
        NSLog(@"array2: %@",keysArray[column][row]); //EXC_BAD_ACCESS here
    }
}

What would cause this to happen, given that the keysArray is defined in the method body, outside of both sets of loops?

Thanks

+1  A: 

Are the contents of anotherArray retained by some other object? If not, they do not exist anymore in the second loop. WTH are you using a C array to store Objective-C objects anyway?

int c = 4;
int r = 5;
NSMutableArray *keysArray = [[NSMutableArray alloc] initWithCapacity:c];

for (int column = 0; column < c; column++) {
    [keysArray addObject:[NSMutableArray arrayWithCapacity:r]];
    for (int row = 0; row < r; row++) {
        [[keysArray objectAtIndex:column] addObject:[anotherArray objectAtIndex:0]];
        [anotherArray removeObjectAtIndex:0];
    }
}

for (int row = 0; row < r; row++){
    for (int column = 0; column < c; column++) {            
        NSLog(@"array2: %@", [[keysArray objectAtIndex:column] objectAtIndex:row]);
    }
}
Ole Begemann
I need a multidimensional array to store row/column positions of buttons in a grid, using a C array was the simplest way i could think of, unless you could suggest a more appropriate method? Why should it matter if anotherArray is retained elsewhere, aren't its contents stored in keysArray now anyway? The anotherArray is an ivar.
joec
It's not about `anotherArray` being retained, it's about its contents. By removing them from the array, they are being released. If you are not retaining them elsewhere, they will be deallocated. A two-dimensional array is just an array of arrays. You can easily accomplish that with `NSMutableArrays`, too: `[[columns objectAtIndex:column] objectAtIndex:row];`
Ole Begemann
OK i have implemented it using objective c arrays now, but still failing at this point. Does storing them in the mutable array not retain them?
joec
Which array would i access in the second loop, using your example?
joec
I get this error when i try your idea: `*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 0 beyond bounds for empty array'`
joec
That's right, there was an error in the code. I'm typing this without testing, why don't you engage the debugger and go through it yourself. This isn't rocket science.
Ole Begemann
I appreciate your help for this, this problem has been bugging me for ages and i'm just getting tangled up. Its still EXC_BAD_ACCESS'ing on the second time the method is called. I think the problem is like you first said about the objects being released, but anotherArray is an instance variable and i tried `retain`'ing the value when its added, but it still crashes... Where would be the best place to retain the array?
joec
A: 

Could this be the problem :

[anotherArray removeObjectAtIndex:0];
kukudas
A: 

try

keysArray[column][row] = [[anotherArray objectAtIndex:0] retain];

although if I were you I would use NSMutableArray of NSMutableArray instead

Anders K.
I would create a new class to wrap the C array
JeremyP
@JeremyP yes that would be even better.
Anders K.
A: 

You need to retain the objects held in your C array. Unlikes an NS*Array, a C array does not retain on adding to the array.

However, for a no-holes 2D array like that, I'd just use a single NSMutableArray. Any N-dimensional array can be represented as a line-- as a one dimensional array-- with simple math.

Namely, to determine the index of an object at (X,Y), use (Y * width) + X).

The only caveat is that NS*Array does not support "holes". You will need to fill the array row by row. That is, for a 3x4 (3 wide, 4 tall) array, you would fill it in the order 0,0, 1,0, 2,0, 0,1, 1,1, etc...

Obviously, insert and remove operations will mess up your 2D representation (but they would in an NSMutableArray of NSMutableArrays, too).

Alternatively, use NSPointerArray as it can have holes.

bbum