The dimensions are unknown at compile time, so I'm trying to allocate a 2D array of structs dynamically. The code compiles but I get a bad access when accessing an element.
// The struct
typedef struct
{
NSInteger numActors;
Actor *a1;
Actor *a2;
Actor *a3;
Actor *a4;
Actor *a5;
} GridNode;
// In interface
GridNode **grid;
// In init
NSInteger nx = inFrame.size.width / blockSize;
NSInteger ny = inFrame.size.height / blockSize;
grid = malloc(sizeof(GridNode) * nx * ny);
grid[10][20].numActors = 3; // EXC_BAD_ACCESS
C has only 1D arrays, so 2D ones can be defined in two ways:
As an array of arrays, like GridNode **grid
, so to be accessed by grid[x][y]
, but then you have to init each row separately (right, as yehnan managed to anwser first):
grid=malloc(sizeof(GridNode*)*nx);
for(int e=0;e<nx;e++) grid[e]=malloc(sizeof(GridNode)*ny);
As a 1D array with tricky indexing:
grid=malloc(sizeof(GridNode)*nx*ny);
grid[(10-1)*nx+20] //grid[10,20]
Roughly the code should look like:
grid = (GridNode **) malloc(sizeof(GridNode *) * nx);
int i;
for(i = 0; i < nx; i++) {
grid[i] = (GridNode *) malloc(sizeof(GridNode) * ny);
}
And remember to free them.
A simpler alternative would be to create a single-dimension NSArray
or NSMutableArray
and use a little math to access the correct row and column:
NSUInteger width = 10;
NSUInteger height = 10;
NSUInteger size = width * height;
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:size];
To insert a GridNode
at row 5, column 3, you could do this:
NSUInteger index = (row - 1) * width + col;
[array insertObject:myNode atIndex:index];
To retrieve a node from row 2 column 6 you would do:
NSUInteger index = (row - 1) * width + col;
[array objectAtIndex:index];
The memory in your computer is of a single dimension. The multi-dimensional addressing that we're all familiar with from C is really just syntactic sugar that performs a similar operation as I've shown above.
The only caveat I can think of is that you will probably have to convert GridNode
from a C structure to an Objective-C class for this to work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With