1

How can I specify that a method should take as parameter a pointer to a location in memory that can hold a specified number of values? For example, if I have:

- (void)doSomethingWith:(int *)values;

I'd like to make it clear that the int * passed in should point to an allocated space in memory that's able to hold 10 such values.

rid
  • 61,078
  • 31
  • 152
  • 193

3 Answers3

1

Why use "(int *)" when you have the power (and "count") of "NSArray" to work with?

But anyways, looking at this potentially related question, couldn't you just do a "sizeof(values)" to get the size of a statically/globally allocated pointer?

If that doesn't work (which would be in the case of a dynamically allocated array), you really would probably need some kind of "count:" parameter in your "doSomethingWith:" method declaration.

Community
  • 1
  • 1
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • So it's not possible to specify how large the memory pointed to should be? – rid Jun 09 '12 at 05:49
  • If you're doing the allocating at run time and are not passing in the size (or count of ints) as a parameter to that function, then no. – Michael Dautermann Jun 09 '12 at 05:50
  • +1 for `NSArray` (or other high-level solution). However, be careful with `sizeof()` suggestions. They can be confusing. For instance, it doesn't matter how an array was allocated (static/global/auto vs. heap). It matters that the type is still an array or has it been demoted to just a pointer. In the scope of `int foo[7];`, then `sizeof(foo)/sizeof(foo[0])` gives 7, but pass `foo` to a function and that function can't use `sizeof` to figure out the length because it's received a pointer, not an array. Attempts to use `sizeof` will give bogus results (effectively `sizeof(int*)/sizeof(int)`). – Ken Thomases Jun 09 '12 at 06:06
1

There are a several ways. You could just name the method appropriately:

- (void)doSomethingWithTenInts:(int *)tenInts;

Or you could use a struct:

typedef struct {
    int values[10];
} TenInts;

- (void)doSomethingWithTenInts:(TenInts *)tenInts;

Or you could make the user tell you how many ints he is giving you:

- (void)doSomethingWithInts:(int *)ints count:(int)count;
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
1

To directly answer your question, use an array argument with a bounds, e.g.:

- (void)takeTenInts:(int[10])array

Which specifies that the method takes an array of 10 integers.

Only problem is the C family of languages do not do bounds checking, so the following is valid:

int a[10], b[5];

[self takeTenInts:a]; // ok
[self takeTenInts:b]; // oops, also ok according to the compiler

So while you are specifying the size, as you wish to do, that specification is not being enforced.

If you wish to enforce the size you can use a struct:

typedef struct
{
   int items[10];
} TenInts;

- (void)takeTenInts(TenInts)wrappedArray

Now this doesn't actually enforce the size at all[*], but its as close a you can get with the C family (to which the word "enforcement" is anathema).

If you just wish to know the size, either pass it as an additional argument or use NSArray.

[*] It is not uncommon to see structures in C following the pattern:

typedef struct
{
   // some fields
   int data[0];
} someStruct;

Such structures are dynamically allocated based on their size (sizeof(someStruct)) plus enough additional space to store sufficient integers (e.g. n * sizeof(int)).

In other words, specifying an array as the last field of a structure does not enforce in anyway that there is space for exactly that number of integers; there may be space for more, or fewer...

CRD
  • 52,522
  • 5
  • 70
  • 86