1

In the following code, when I print sizeof(arr) in main(), I get output 32. However when I send the same array to a function print() and print out sizeof(arr), I get 8.

My question is, shouldn't they both be 8, because arr is a pointer to the first element in both cases?

Code:

#include <iostream>

using namespace std;

void print(int arr[])
{
    cout << "from function print(): " << sizeof(arr);
}

int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8 };

    cout << "from main: " << sizeof(arr) << endl;

    print(arr);

    return 0;
}

Output:

main.cpp:8:46: warning: ‘sizeof’ on array function parameter ‘arr’ will return size of ‘int*’ [-Wsizeof-array-argument]                       
main.cpp:5:20: note: declared here                                                                                                            
from main: 32                                                                                                                                 
from function print(): 8                                                                                                                      
                                                                                                                                              
...Program finished with exit code 0                                                                                                          
Press ENTER to exit console.  
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
AYUSHI NIGAM
  • 97
  • 1
  • 5
  • The duplicate does not answer the question: *shouldn't they both be 8, because arr is a pointer to the first element in both cases?* Voting to reopen. – anastaciu Aug 05 '20 at 09:54
  • In general passing an array to a function will be "converted" to a pointer to first element. That is happen here and results in the size of the pointer and not of the array content. So it feels a duplicate... anyway, you have a lot of answers with more or less repetitions of all that things... – Klaus Aug 05 '20 at 10:00
  • @Klaus, though I agree this is a common matter, it's usually the other way around, in this case the question is about why sizeof is able to find out the total size of an array type. – anastaciu Aug 05 '20 at 10:02

2 Answers2

2

My question is, shouldn't they both be 8, because arr is a pointer to the first element in both cases?

An array name is not a pointer. In main, where arr is declared and initialized you will get the real size of arr, which in your case is 32 bytes, 8 times(the number of elements) 4(your system int type size).

sizeof is able to calculate the total size of the array because it's an array type, this is mandated by the C++ standard:

[expr.sizeof]

[...] When [sizeof is] applied to an array, the result is the total number of bytes in the array. This implies that the size of an array of n elements is n times the size of an element.

In

void print(int arr[]){/*...*/}

You're right, the int arr[] argument will decay to a pointer to arr, so sizeof(arr) is the size of the pointer, sizeof is not able to find the size of an object pointed by the pointer passed to it as an argument, it will render the size of the pointer instead, which in your system is 8 bytes, as it usually is in a 64 bit system.

As you are using an expression instead of a type you can remove the parenthesis and use sizeof arr only.

On a side note, using namespace std; is not advised.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • 2
    @AYUSHINIGAM You seem not to have understood the answer. `arr` in `main` is an array, but `arr` in `print` is a pointer. There is no way to get the size of an array from a pointer (or even to know if the pointer is pointing to an array). – john Aug 05 '20 at 09:12
  • 1
    @AYUSHINIGAM, it's a matter of the type, for arrays, sizeof is able to calculate the total size of the array, because it's an array type, whereas in a pointer type, sizeof will render the size of the type, it will not dereference or access the values pointed by the pointer in any way. – anastaciu Aug 05 '20 at 09:25
  • @AYUSHINIGAM, I added some documentation to the answer that may clarify your doubts. – anastaciu Aug 05 '20 at 09:50
1

arr is not a pointer to the first element in both cases. In main arr is an array. In print arr is a pointer. When print is called the name of the array arr is converted to a pointer to its first element.

So in main sizeof knows that arr is an array and calculates it's total size. But in print all sizeof knows is that arr is a pointer, It doesn't know that it's pointing to the first element of an array. In fact there is no reason that it must point to the first element of any array. In main you could have print(arr + 1);, now arr in print is pointing to the second element of the array. Or you could have int num = 1; print(&num); now arr in print isn't pointing to an array at all.

So all sizeof in print knows is that arr is a pointer, and so it gives you the size of that pointer.

For all these reasons (and many more) you don't see arrays being used all that much in C++. Most of the time you should prefer to use std::vector. Vectors are superior to arrays for most purposes.

john
  • 85,011
  • 4
  • 57
  • 81
  • 1
    If one has a known size, `vector`s are not superior, because they incur dynamic allocation for no reason. In that case, `std::array` is superior to both C-style arrays and `std::vector`, because it carries its size with it (and is copyable, etc.) and does not require dynamic allocation. – underscore_d Aug 05 '20 at 09:53