2

I am a bit of a beginner to OOP so this may be a silly question!

I would like to use a multidimensional CArray as an instance variable in an objective-c class, and would also like to be able to specify it's size during runtime, during the objects initialisation method:

@interface ArrayClass : NSObject {

int array[][];

}

-(id)initWithSizeX:(int)sizeX sizeY:(int)sizeY;

@end

This produces the error "Instance variable 'array' has unknown size."

I can only seem to make use of the array if I declare it as having an initial size, say [20][20] for example - But that of course defeats the point because I want it to be decided at runtime!

My guess that is this is necessary as the objects memory footprint needs to be known up front?

Does anybody know if what I am trying to this is possible at all? Are there any workarounds that would allow me to size the array at runtime? Or am I going about this in completely the wrong way?

I know there are a lot of topics about multi-dimensional arrays, but I cannot seem to find anything that answers my question!

1
  • If it needs to be dynamic, then perhaps make it so. NSMutableArray may give you what you're looking for, while staying in Obj-C land. You may need to do the multi-dimension work via index arithmetic, but that is easy enough in two dimensions. Does it have to be a C-array ? Commented Nov 7, 2012 at 22:36

2 Answers 2

3

Since you're working in Objective-C, you might consider using NSArray (or NSMutableArray depending on what you plan on doing with the array). This will let you send it Objective-C messages and get a lot more functionality "for free" due to it being an object, not just a chunk of memory (as an array is in C). Also, if you're using ARC or garbage collection, it will get memory managed for you.

But if you know you want to use a C array (which is totally valid), you'll need to malloc it (and free it when you're done with it) in your code just like you would normally in C. (You can only get around this when you create a static array of a defined size at compile time, as you noted.)

EDIT: As @Mahesh pointed out in the comments, you'll want to declare your array variable as
int **array;
instead of
int[][] array;.

Take a look here if you need more help with this!

Sign up to request clarification or add additional context in comments.

3 Comments

+1 If the OP needs to go C way, then int ** is what needed.
Thank you, I will try this out and see how it goes! I didn't think of doing it that way. Trying to get my head around object oriented programming is making me forget things I ought to know about C, I think! I would prefer to use the C array because I only need basic functionality, and I worry a little about the performance impact that creating too many NSNumber objects could cause if my array is very large!
Yes, if all you need to do is store a 2D array of ints, it's definitely wasteful to have to shove them into NSNumber objects just to hold them in an NSArray -- a plan 'ole C array is the right choice!
2

Use NSArray or a derivative if possible. If it has to be a C-array, you can do it with a single-linear malloc() and do the arithmetic yourself for the two dimensions. I.e.

int *ar = malloc(sizeof(int) * nrows * ncols);

And access the appropriate "cell" by arithmetic of the offset

// access cell at [n,m]
ar[n*ncols+m] = value;

I generally find this a helluva lot simpler than trying to manage arrays of pointers to arrays of values, but your mileage may vary.

Alternatively, I save this for last in case you want the true 'multi' in multi-dimensioned dynamic arrays without going row-malloc-happy list most suggest, and your C compiler supports an optional feature defined in the C99 standard called VLA (Variable Length Arrays). C99 supports variable array declarations at the implementation level (i.e. the compiler can support the feature as it is defined by the standard, but does not have to; see 6.7.6.2 of the C99 standard for more info). If your compiler does NOT support it, then a predefined macro, __STDC_NO_VLA__ must be defined and can be tested at compile time (see section 6.10.8.3-1 of the C99 standard). That being said, every C99-compliant compiler I've ever used in the last decade-plus does support it, so if your's does not, tell us below in a comment. For the OP, I guarantee yours does if you're using either gcc or llvm with Xcode. For anyone else, just test if __STDC_NO_VLA__ is defined. If it is not, the feature is supported.

int nrows = 10, ncols = 15;
int (*ar)[cols] = malloc(sizeof(int) * nrows * ncols);

Note a couple of things right away. The allocation is exactly the same as before. The variable being declared, however, is a little different. The declaration here of ar dictates it is a pointer to an array of ncols integers. So long as you allocate a multiple of ncols (which we do by multiplying by nrows) the resulting matrix is now accessible with the familiar subscripting you've grown to love:

// for any n'th row, m'th column
ar[n][m] = value;

2 Comments

Thank you for your reply! I like this method actually, I never thought to try implementing a multi-dimensional array in this way... And it does indeed look like it would be simpler to manage!
@tom1990 So long as you bounds-check your [n,m] values before access (0<=n<nrows and 0<=m<ncols), I honestly prefer it this way. This is, in fact, how C lays out a declared multi-dimension array for you (such as int ar[10][20]; so it only seems natural to me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.