Because when you pass an array by value to a function, you're actually passing a pointer (to the first element of the array).
void PrintArrayLength(int arr[])
{
cout << "Function Array length is: " << sizeof(arr)/sizeof(int) << endl;
}
is actually:
void PrintArrayLength(int* arr)
{
cout << "Function Array length is: " << sizeof(arr)/sizeof(int) << endl;
}
Don't be misled by the syntactic sugar that lets you declare an array as int[]
. In reality, there's no such type and what you've really written is:
int arr[3] = {1, 2, 3};
It's just that the compiler can trivially fill in that 3
for you from the initialiser.
As an aside, you can retain the dimensions if you pass your array by reference. For convenience, you can make use of templates so that you only need one function no matter what dimension the array has (as the dimension is part of the type):
template <size_t N>
void PrintArrayLength(int (&arr)[N])
{
cout << "Function Array length is: " << sizeof(arr)/sizeof(int) << endl;
}
An extension to this is the good advice to not use sizeof
. You can easily fall into the trap that you fell into, thinking that you're sizing up an array when, really, you're not. Use this instead:
template <typename T, size_t N>
size_t length_of_array(T (&)[N]) {
return N;
}
Trying to use this function on anything but a proper array will fail with a compiler error, instead of silently giving misleading values like your code did.
Of course, replacing your use of raw arrays with objects of type boost::array
(or std::array
in C++0x) or even std::vector
(which can be resized) is the best approach. :)