I have a function in C (I am using gcc 4.8.0) which receives an array as its argument. Is there a way to accurately determine the number of elements in the array, without passing an additional argument array_count?
-
7Short answer: no. – ouah Oct 05 '13 at 13:18
-
1possible duplicate of [How do I determine the size of my array in C?](http://stackoverflow.com/questions/37538/how-do-i-determine-the-size-of-my-array-in-c) - see Elizeb's answer – quetzalcoatl Oct 05 '13 at 13:20
-
1can you provide a little more explanation? – Lid Oct 05 '13 at 13:20
-
1@Quetzalcoatl Well, not quite a duplicate. – Sachin Joseph Oct 05 '13 at 13:22
-
There is no such "real" thing as an array in C, therefore it can have no attribute such as "length". A C "array" is just a naming trick to ascribe "arrayness" to a sequence of similar elements in storage, addressed with a pointer. There is nothing in the bits of the "array" that indicate it's an array of any size, vs just a sequence of (perhaps unrelated) data. – Hot Licks Oct 05 '13 at 13:23
-
1@SachinJoseph: is is duplicate to tens or hudreds of other questions about finding out "the size of an array". Finding the element count is practically the same thing, assuming you don't work with vague `void*`. IMHO, this question should be instaclosed, I didnt search for exact duplicate, because it would take just too long due to the myriads of almost-exact-dups. The point is, if the author understood "arrays, pointers and memory things", he wouldn't need to ask. And he can learn those things from almost-exact-dups too. – quetzalcoatl Oct 05 '13 at 13:27
-
1@HotLicks: I think that there actually is something as "array", but it is .. temporary. It's in the typename of i.e. `int x[10]`. As long as the typeinformation is present and the 'x' is not cast to `int*`, it is actually an array. `sizeof` proves that by giving you exact size information, from which you can calculate the length (well, mostly). Only after trimming the typeinfo by using pointer casts and arithmetics - you are left with bare pointer. So, arrays exist, but only as long as their true original definition is "in scope". – quetzalcoatl Oct 05 '13 at 13:30
-
@quetzalcoatl - It's purely a notation tacked onto the type in the compiler's symbol table, at compile time. There is no physical identification of the array in the running program. – Hot Licks Oct 05 '13 at 13:58
6 Answers
There is no way to determine in general the number of array elements passed as parameter.
When you pass a array as argument in C, you only pass the pointer to that array, that is the pointer to the first element (indexed 0) of the memory zone holding that array.
Very often, programmers have the convention of passing, as another argument, the size of that array. For example, the standard qsort(3) library function is expecting, as its second nmemb argument, the number of elements in the array to be sorted.
Alternatively, you might use flexible array members, e.g. pass (in C99, not in earlier C standard) address of structures like
struct my_flexarray_st {
int size; // allocated size
int len; // used length, should be less than size
double arr[]; /// only len numbers are meaningful
};
Whatever method you use, you need to understand that array sizes are conventionally known by functions when passed by argument. So please, document that convention. You could even have the (bad) convention that all arrays have some global variable as their dimension.
For heap allocated memory zones, the standard gives you malloc
, calloc
and friends to get such fresh zones, but no way to query their allocated sizes. Some C libraries have non-standard extensions to query that (but I don't recommend using them).
In recent C++11 (which is not the same as the C language) you might be interested by std::vector and std::array template containers.

- 223,805
- 18
- 296
- 547
Arrays decay into pointers in function arguments so size cannot be determined.
An lvalue [see question 2.5] of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T because an array is not a "modifiable lvalue,"
(The exceptions are when the array is the operand of a sizeof or & operator, or is a literal string initializer for a character array.)

- 22,572
- 7
- 65
- 91
You can't , unless the array is static (i.e. not dynamic-allocated) , then you can use sizeof
operator.

- 8,938
- 12
- 37
- 67
Not possible. This is why you either use a data structure like a linked list where you can actually determine the length or you require a length argument in your function. Even with the required length argument alone there is no way to know it is true. So, your API should also require a standard sentinel value to terminate the array. Generally this could be NULL or something but depends on your array type.

- 12,679
- 6
- 37
- 55
This is doable in C. You can query size of array if you are in the same scope of its definition via sizeof. If you are in scope of function which takes array as parameter you need to declare the parameter as pointer to array (not just as array - in this case array will decay to pointer to first element), in this case size of array would be saved during argument passing:
void foo(int (*param)[3] ) { assert (sizeof(*param) == sizeof(int)*3; }
However, if you mean by "array" pointer to some dynamically allocated memory with not-known at compile time size, then you definetely need to pass size separately.

- 184
- 4
-
What you are doing is querying the compiler symbol table, at compile time, to ask what it knows about the symbol. There is no mechanism which will implicitly pass array size on a call. – Hot Licks Oct 05 '13 at 21:48
-
I am not sure what do you mean. In C language there is no facilities to "query compiler symbol table". What the code does is exactly what the description says. Param object refers to pointer of 3 int array and compiler should ensure that one actually pass pointer to 3 int array. Foo function has 3 int array within the scope without passing size separately. For example, when you pass pointer to int, you don't name it "querying the compiler symbol table, at compile time, to ask whether pointer to int is really pointer to int". – mfxm Oct 05 '13 at 22:28
-
Whatever is declared as the parameter is what you get -- no size information is "passed" on the call. And the C language does indeed have a facility to query the compiler symbol table -- it's called `size`. – Hot Licks Oct 05 '13 at 22:48
-
*For example, when you pass pointer to int, you don't name it "querying the compiler symbol table, at compile time, to ask whether pointer to int is really pointer to int"* -- You don't name it that, but that's what happens. – Hot Licks Oct 05 '13 at 22:50
-
If you mean 'sizeof' than if you go to documentation you will found that it has nothing to do with 'querying compiler symbol table'. – mfxm Oct 06 '13 at 06:24
-
1From language point of view, it provides tool to determine size of array (in both cases of local and parameter scope if it is correctly passed). From practical point, when one speaks about array he often means pointer to dynamically allocated memory and size of the block. In such cases, compiler can by no means detect at compile time size of array. So, user has a tradeoff - either work with arrays (as they are defined by language) of fixed size or with "arrays" (as he calls pointers to d.a. memory) and pass size separately. – mfxm Oct 06 '13 at 06:26
-
-
Right question is what is 'sizeof' in C and the answer is "The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand... When applied to an operand that has array type, the result is the total number of bytes in the array." Programmer should not care 'where the value comes from' (you can define C as a language with symbol table and programmer querying it, but it is not the way C is defined). – mfxm Oct 06 '13 at 12:08
-
But it's a compile-time number, purely derived from the declaration. The declaration is in the symbol table. There is no run-time construct, no real "method" called. – Hot Licks Oct 06 '13 at 12:56
you can do a while look
function(arr[])
{
/* not this is pseduo code */
int i = 0;
while (*arr[i++] != null)
{
}
// i is number of elements
}

- 16,560
- 16
- 115
- 136
-
This is possible, iff the array is prepared to having a sentinel representing its end in a doubt-free way. If it hasn't, it is not possible. – glglgl Oct 05 '13 at 13:33
-
Very very very bad piece of code. You'd do better if you'd overallocate the array and put the length at "arr[-1]" or after te last element. Think: what if your array is filled in 100%? How can you be sure that NULLs really AFTER the array? – quetzalcoatl Oct 05 '13 at 13:34