Search code examples
c++pointerspass-by-referenceimplicit-conversionpass-by-value

why do I see different values of array size in main vs other function


I created an array of ten integers and print its size 1. in main 2. in a function named print

#include <iostream>
using namespace std;
void print(int *a)
{
    cout<<sizeof(a);
}
int main()
{
    int arr[10];
    cout<<sizeof(arr)<<endl;
    print(arr);
}

The output is :

40

8

I was expecting 40 in both cases (as size of 1 integer=4 times 10 ) but the second case shows size of a single pointer and not the whole array. What's happening here?


Solution

  • As you can see from the function declaration

    void print(int *a)
    {
        cout<<sizeof(a);
    }
    

    the function deals with a pointer. So this statement

    cout<<sizeof(a);
    

    outputs the size of the pointer that is equal either 4 or 8 bytes depending on the used system.

    Pay attention to that even if you will declare the function like

    void print(int a[])
    {
        cout<<sizeof(a);
    }
    

    you will get the same result because the parameter is implicitly adjusted by the compiler to the type int *.

    That is the previous and this function declarations are equivalent.

    If you want that the function would deal with the original array instead of a pointer that points to the first element of the passed array as an argument then declare the function at least like.

    void print( int ( &a )[10] )
    {
        cout<<sizeof(a);
    }
    

    That is declare the parameter as a reference.

    Or you can make the function a template function like

    template <size_t N>
    void print( int ( &a )[N] )
    {
        cout<<sizeof(a);
    }
    

    As the passed array is not being changed in the function then the parameter should have the qualifier const

    template <size_t N>
    void print( const int ( &a )[N] )
    {
        cout<<sizeof(a);
    }
    

    Here is a demonstrative program.

    #include <iostream>
    
    template <size_t N>
    void print( const int ( &a )[N] )
    {
        std::cout << sizeof( a ) << '\n';
    }
    
    int main() 
    {
        int arr[10];
    
        std::cout << sizeof( arr ) << '\n';
    
        print( arr );
    
        return 0;
    }
    

    Its output is

    40
    40
    

    Or you could define the template function with a type template parameter. But again the function parameter has a referenced type.

    #include <iostream>
    
    template <typename T>
    void print( const T &a )
    {
        std::cout << sizeof( a ) << '\n';
    }
    
    int main() 
    {
        int arr[10];
    
        std::cout << sizeof( arr ) << '\n';
    
        print( arr );
    
        return 0;
    }
    

    The program output will be the same as shown above.