views:

121

answers:

4

I have this function:

int setIncludes(char *includes[]);

I don't know how many values includes will take. It may take includes[5], it may take includes[500]. So what function could I use to get the length of includes?

A: 

You have to know the size either way. One way would be to pass the size as a second parameter. Another way is to agree with the caller the he/she should include a null pointer as the last element in the passed array of pointers.

AraK
+5  A: 

There is none. That's because arrays will decay to a pointer to the first element when passing to a function.

You have to either pass the length yourself or use something in the array itself to indicate the size.


First, the "pass the length" option. Call your function with something like:

int setIncludes (char *includes[], size_t count) {
    // Length is count.
}
:
char *arr[] = {"Hello,", "my", "name", "is", "Pax."};
setIncludes (arr, sizeof (arr) / sizeof (*arr));
setIncludes (arr, 2); // if you don't want to process them all.

A sentinel method uses a special value at the end to indicate no more elements (similar to the \0 at the end of a C char array to indicate a string) and would be something like this:

int setIncludes (char *includes[]) {
    size_t count = 0;
    while (includes[count] != NULL) count++;
    // Length is count.
}
:
char *arr[] = {"Hello,", "my", "name", "is", "Pax.", NULL};
setIncludes (arr);

Another method I've seen used (mostly for integral arrays) is to use the first item as a length (similar to Rexx stem variables):

int setIncludes (int includes[]) {
    // Length is includes[0].
    // Only process includes[1] thru includes[includes[0]-1].
}
:
int arr[] = {4,11,22,33,44};
setIncludes (arr);
paxdiablo
So like a max value?
Mohit Deshpande
Assuming you mean the first one, @Mohit, sort of. The `sizeof` trick will always get you the length of the array (assuming it hasn't already been decayed to a pointer). The flexibility is that you're not limited to passing that value. If you have an array of size 1000 but only 20 useful values in it, you can pass 20 as the size.
paxdiablo
Why are you passing an array of `int` to a function that expects an array of `char *`?
caf
@caf, that's a good point and all I can say in my defence is "I'm an idiot!" :-) I'm not sure why I thought they were integer arrays though I may have been working on two different questions concurrently. Fixed now.
paxdiablo
+2  A: 

You have two options:

  1. You can include a second parameter, similar to:

    int main(int argc, char**argv)

  2. ... or you can double-null terminate the list:

    char* items[] = { "one", "two", "three", NULL }

sukru
Interestingly, for the special case of `main(int argc, char *argv[])`, the C standard requires that the caller both pass the right count *and* include a NULL pointer at `argv[argc]`. Belts and suspenders, true, but it has merit.
RBerteig
+1  A: 

There is no way to simply determine the size of an arbitrary array like this in C. It requires runtime information that is not provided in a standard way.

The best way to support this is to take in the length of the array in the function as another parameter.

JaredPar