Reputation: 1183
Hello i am trying to write a function which return the number of elements of the array passed as parameter, the function have to work on an array of any type.
I tried this:
int nb_elems(void* array)
{
void* end = array;
while(*end != NULL) // The last element have to be null, it is not counted.
end++;
return end - array;
}
As you can guess, it doesn't work.
In fact it doesn't even compile, i get these errors:
Error: Illegal indirection. < while(*end != NULL) >
Error: void * : size unknown. < while(*end != NULL) >
Error: void * : size unknown. < return end - array >
First, could you tell me if what i am trying to do is possible?
Second, is the way i am trying to achieve this makes sense, or am i completely missing the point?
Then, why do i get these errors, what does they means?
Thanks for your help!
Upvotes: 1
Views: 1259
Reputation: 17413
If you have an actual array, not a pointer, you can use sizeof(array) / sizeof(array[0])
to determine the number of elements in it.
Upvotes: -1
Reputation: 1670
because you are checking != NULL
i suppose you have an array of pointers. with array of pointer your code could work because you know the size of pointers even if it is a void pointer.
if my assumptions were right you could code it like this:
int nb_elems(void** array) {
void** end = array;
while(*end != NULL) {
end++;
}
return end - array;
}
but this code only works with pointer to pointer or array of pointer.
usage:
int** iptrs = (int**)malloc(3 * sizeof(int*));
iptrs[0] = (int*)malloc(sizeof(int));
*(iptrs[0]) = 42;
iptrs[1] = (int*)malloc(sizeof(int));
*(iptrs[1]) = 23;
iptrs[2] = NULL;
printf("%d", nb_elems(iptrs));
the example prints 2
Upvotes: 1
Reputation: 153660
As C does not pass arrays, nb_elems(void* array)
received a pointer. The void *pointer
does not know how many elements (nor the type) which its points to.
Since it needs to "work on an array of any type", code needs to define how to compare an arbitrary type with NULL
.
To your function, you need to pass the pointer, the size of an array element and a function to use to test against NULL
.
int nb_elems(void* array, size_t esize, int (*cmp)(void *ptr)) {
char *ptr = array;
int count = 0;
while (*cmp(ptr) == 0) {
ptr += esize;
count++;
}
return count;
}
Upvotes: 3
Reputation: 983
The reason your code doesn't compile, is because of the fact that the compiler cannot determine the size of a void. Take for example the ++ operator. We could roughly translate this to:
end = end + sizeof(void);
The size of a void is not defined, so the compiler cannot generate any code for this, giving you one error.
Next you try to dereference a void pointer. This would give you something with the type void. But since a void does not represent anything (it represents nothing), the compiler cannot tell what this should be. You then use the equality operator to compare nothing to NULL. You cannot compare nothing to something, so this will generate an error.
In C, it is impossible to implement a function that would do something like this, simply because of the fact that you cannot tell what the type of the void* will be. You at least need to know the type your passed to your function and what type-specific value will be used to terminate the array. C does not offer this functionality, making the implementation of such a function impossible.
Upvotes: 1
Reputation: 78923
No, the way your are doing it is not possible, because to do pointer arithmetic (here the ++
and the -
) the compiler has to know the size of the base type of the array.
Also void*
is a pointer to void
, that is to a "non-type". So *end
has type void
and you can't compare it to anything, in particular not to NULL
, which could be a pointer type or an integer. Just use 0
if you compare a base type for being zero.
Before starting to even try to do this for pointers of any type, you should try the same for pointers to a known type, say unsigned
or double
. If you change your code with that in mind, it has good chances to work.
Upvotes: 1