Arun Suryan
Arun Suryan

Reputation: 1695

Sizeof operator with pointer variables vs. arrays

I know that the sizeof operator returns the size of any given type in C/C++. In C style arrays the name of the array is a pointer itself that points to the first element of the array. For example, in int arr[2] = {2, 3}, *arr will yield 2. Then why the sizeof operator does not return the size of the pointer variable, instead it returns the total size occupied by the array in the memory.

See this code:

#include <iostream>
using namespace std;

int main()
{
    int arr[10];

    cout << sizeof (arr);
    return 0;
}

Output: 40 bytes (Given int takes 4 bytes)

What I want to ask in this code is that even if arr is just a pointer then how does sizeof returns the entire size occupied by this array?

I wrote my own sizeof to understand it:

#include <iostream>
using namespace std;

template <typename T>
size_t my_sizeOf(T var)
{
    return (char *) (&var + 1) - (char *) (&var);
}

int main()
{
    int arr[10];

    cout << my_sizeOf(arr);
    return 0;
}

Output: 8 bytes (Given pointer variable takes 8 bytes)

And this code prints only the size of the pointer variable now. Am I missing some crucial point about the sizeof operator?

Upvotes: 1

Views: 678

Answers (2)

cigien
cigien

Reputation: 60208

In C++, the declaration of int arr[10]; declares arr to be of type int[10], i.e. an array of 10 ints. Since the size of the array is part of the type of arr, the sizeof operator knows what the size actually is.

In your function my_sizeOf, you are decaying arr to a pointer in the function parameter, and so you get the size of a pointer instead of the size of an array. The correct way to write your function would be

template <typename T, size_t N>
size_t my_sizeOf(T (&)[N])
{
  return N;
}

Upvotes: 3

Silvio Mayolo
Silvio Mayolo

Reputation: 70257

#include <iostream>
using namespace std;

int main()
{
    int arr[10];

    cout << sizeof (arr); // 40
    return 0;
}

arr is not just a pointer. It is an array, with size 10. Arrays can decay into pointers when passed to functions, but the types int[10] and int* are distinct types with different sizes.

Note that, if we force it to be a pointer, we get the result you're expecting.

#include <iostream>
using namespace std;

int main()
{
    int arr[10];

    cout << sizeof ((int*)arr); // 8 (on 64-bit systems)
    return 0;
}

On the other hand, if you dynamically allocate an array (which you should not do; 99% of the time, std::vector is better and smarter), then you have to store it in a pointer, not an array variable.

#include <iostream>
using namespace std;

int main()
{
    int* arr = new int[10];

    cout << sizeof (arr); // 8 (on 64-bit systems)
    delete[] arr;
    return 0;
}

Of particular note, sizeof is not a function and does not evaluate its argument. It's a special keyword and it only uses the type of its argument.

Upvotes: 5

Related Questions