Why isn\'t the size of an array sent as a parameter the same as within main?
#include
void PrintSize(int p_someArray[10]);
int main () {
In C language when you pass the array as an argument to the function , it is automatically converted into pointer ,array passing from one function other function is know as call by reference . That is the reason the called function only receives the pointer which point to the first element of function This is the reason
fun(int a[]) is similar to fun(int *a) ;
so when you print the size of array it will print the size of first element.
An array-type is implicitly converted into pointer type when you pass it in to a function.
So,
void PrintSize(int p_someArray[10]) {
printf("%zu\n", sizeof(p_someArray));
}
and
void PrintSize(int *p_someArray) {
printf("%zu\n", sizeof(p_someArray));
}
are equivalent. So what you get is the value of sizeof(int*)
Arrays are only loosely sized. For the most part, an array is a pointer to memory. The size in your declaration only tells the compiler how much memory to allocate for the array - it's not associated with the type, so sizeof() has nothing to go on.
The behavior is by design.
Same syntax in function parameter declaration means completely different thing than in local variable definition.
The reason is described in other answers.
So, you will need to pass the lenght of the array as a second parameter. When you are writing code, in which you both declare an array of constant size, and later pass that array to a function, it is a pain to have the array-length constant show up several places in your code...
K&R to the rescue:
#define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
So now you can do e.g:
int a[10];
...
myfunction(a, N_ELEMENTS(a));
The behavior you found is actually a big wart in the C language. Whenever you declare a function that takes an array parameter, the compiler ignores you and changes the parameter to a pointer. So these declarations all behave like the first one:
void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
a will be a pointer to int in all four cases. If you pass an array to func, it will immediately decay into a pointer to its first element. (On a 64-bit system, a 64-bit pointer is twice as large as a 32-bit int, so your sizeof ratio returns 2.)
The only purpose of this rule is to maintain backwards compatibility with historical compilers that did not support passing aggregate values as function arguments.
This does not mean that it’s impossible to pass an array to a function. You can get around this wart by embedding the array into a struct (this is basically the purpose of C++11’s std::array):
struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0])); /* prints 5 */
}
or by passing a pointer to the array:
void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints 5 */
}
In case the array size isn’t a compile-time constant, you can use the pointer-to-array technique with C99 variable-length arrays:
void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints n */
}