How do sizeof(arr) / sizeof(arr[0]) work?
Asked Answered
H

8

62

When looking for a size of an array in a for loop I've seen people write

int arr[10];
for(int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){}

How is sizeof(arr) / sizeof(arr[0]) the length of the array? How does it technically work?

Hoarsen answered 4/11, 2015 at 13:50 Comment(2)
Add the definition of arr to the question otherwise it's ambiguous.Illampu
@Illampu It says it is an array, and the code gets the length of the array, so it is safe to assume arr is an array.Harlanharland
C
81

If you have an array then sizeof(array) returns the number of bytes the array occupies. Since each element can take more than 1 byte of space, you have to divide the result with the size of one element (sizeof(array[0])). This gives you number of elements in the array.

Example:

std::uint32_t array[10];

auto sizeOfInt = sizeof(std::uint32_t); // 4
auto numOfBytes = sizeof(array); // 10*sizeOfInt = 40
auto sizeOfElement = sizeof(array[0]); // sizeOfInt = 4
auto numOfElements = sizeof(array) / sizeof(array[0]); // numOfBytes / sizeOfElement = 40 / 4 = 10

LIVE EXAMPLE

Note that if you pass an array to a function, the above won't work since the array decays to a pointer and sizeof(array) returns the size of the pointer.

std::size_t function(std::uint32_t a[]) // same for void function(std::uint32_t a[10])
{
    return sizeof(a); // sizeof(std::uint32_t*)!
}

std::uint32_t array[10];
auto sizeOfArray = function(array); // array decays to a pointer inside function()

LIVE EXAMPLE #2

Chophouse answered 4/11, 2015 at 13:52 Comment(7)
if we write "array.length", does that mean we also get the correct answer in all cases ? Or is there any exception ?Abulia
@Texas_September_2020 There is no array.length for C arrays. If you mean std::array::size(), then yes, that is the same.Chophouse
You are right that for C language, there is no way to get "array.length". But, for C#, there is an a public method to get array length as follow: "public int Length { get; }". There are good examples for C# : learn.microsoft.com/en-us/dotnet/api/…Abulia
You do realise this is a C++ question and answer?Chophouse
BTW, It's true as you wrote: in C++11 or newer versions, we can also call simply "array.size()", and that will return the exact length of the array. For the older versions of C++, we still need to do the long calculation: "sizeof(arr) / sizeof(arr[0])". I just want to add a note about "the version C++11 or newer versions" to your comment to clarify in case someone needs to know. It's 2020 now. So, I assume that most people are using the newer versions of C++. :-)Abulia
@Abulia array.length works in Javascript. And yes, you get the correct number of elements because Js is a high-level language unlike C++.Nazi
We could define a function like: template <typename T, size_t N> size_t sizeof_array(const T(&)[N]) { return N; } So that we can deduce the size of C arrays.Rooftop
Z
15

As it is described in the C++ Standard (5.3.3 Sizeof)

1 The sizeof operator yields the number of bytes in the object representation of its operand. The operand is either an expression, which is an unevaluated operand (Clause 5), or a parenthesized type-id.

In this expression

sizeof(arr) / sizeof(arr[0])

there are used two subexpressions with the sizeof operator.

This subexpression

sizeof(arr)

yields the number of bytes occupied by array arr (I suppose that arr is an array).

For example if you declared an array like

int arr[10];

then the compiler has to reserve memory that to hold 10 elements of type int. If for example sizeof( int ) is equal to 4 then the compiler will reserve 10 * 4 = 40 bytes of memory.

Subexpression

sizeof(arr[0])

gives the number of bytes occupied by one element in the array. You could use any index as for example

sizeof(arr[1000])

because the expression is unevaluated. It is only important the size in bytes of the object (an element of the array) used inside the operator.

Thus if you know the total bytes that were reserved for an array

sizeof(arr)

and know how many bytes each element of the array occupies (all elements of an array have the same size) then you can calculate the number of elements in the array by using the formula

sizeof(arr) / sizeof(arr[0])

Here is a simple relation. If you have an array of N elements of type T

T arr[N];

and you know the size of the memory occupied by the array then you can calculate the size of its element by using formula

sizeof( arr ) / N == size of an element of the array. 

And vice verse

If you know the size of the memory occupied by the array and the size of its element you can calculate the number of elements in the array

sizeof( arr ) / sizeof( a[0] ) == N - number of elements in the array

The last expression you can rewrite also the following way

sizeof( arr ) / sizeof( T ) == N - number of elements in the array

because the elements of the array have type T and each element of the array occupies exactly the number of bytes that are required to allocate an object of type T.

Take into acccount that usually beginners make such an error. They pass an array as an argument to a function. For example let's assume that you have a function

void f( int a[] )
{
   // ...
}

And you pass to the function your array

int arr[10];
f(arr);

then the function uses the pointer to the first element of the array. In fact the function has declaration

void f( int *a )
{
   // ...
}

So if you write for example within the function

void f( int *a )
{
   size_t n = sizeof( a ) / sizeof( a[0] );
   // ...
}

then as a within the function is a pointer (it is not an array) then you will get something like

void f( int *a )
{
   size_t n = sizeof( int * ) / sizeof( int );
   // ...
}

Usually the size of a pointer equal to either 8 or 4 bytes depending of the used environment. And you won't get the number of elements. You will get some weird value.

Zeph answered 4/11, 2015 at 14:1 Comment(4)
I wonder, can i use int arr[10]; int length = sizeof(arr)/sizeof(*arr); ??Gallardo
@FitriHalim arr[0] is evaluated like *( arr + 0 ) that is the same as *arr. So these expressions are equivalent.Zeph
Which one is more readable/standard?Gallardo
@FitriHalim It is opinion based. I prefer to use sizeof( arr ) / sizeof( *arr ).Zeph
B
12

int - is equal to 4 bytes
sizeof(int) it means: 1 * 4 = 4

int arr[10] - is holding 10 int
sizeof(arr) it means: 10 * 4 = 40, we got 10 int and every int got 4 bytes,, arr without the [] it means all the arr.

sizeof(arr[0]) it means: 1 * 4 = 4

sizeof(arr) / sizeof(arr[0]) = 10*4 / 1*4 = 10,, and it is the length of the array.

Blackmarket answered 23/7, 2018 at 13:20 Comment(0)
P
8

It only works if arr has not been decayed into a pointer, that is, it is an array type, not a pointer type.

sizeof(arr) is the total size occupied by the array.

sizeof(arr[0]) is the size of the first element in the array. (Note that zero length arrays are not permitted in C++ so this element always exists if the array itself exists).

Since all the elements will be of the same size, the number of elements is sizeof(arr) / sizeof(arr[0]).

Portecochere answered 4/11, 2015 at 13:53 Comment(0)
E
1

When dealing with an array (some_type name[some_size]) sizeof(name) is how many bytes the array occupies. Dividing the total size of the array by the size of one element (sizeof(name[0])) gives you how many elements are in the array.

Ere answered 4/11, 2015 at 13:54 Comment(0)
J
0

c++ way to use extent, which allows u to get a number of elements in Nth dimension of the array. see http://en.cppreference.com/w/cpp/types/extent for details

int values[] = { 1 };

std::extent<decltype(values)>::value == 1
Judaism answered 26/3, 2018 at 13:28 Comment(2)
Could you extend your answer?Ovida
Only if you don't have an object. In that case, the more general std::size() is more elegant.Neurotic
S
-2

Let's take an example like the arr[]={1,2,4,3,5}.

Then the size of the array will be 5 and the size of arr[0] will be "1" BECAUSE it consists of an element in it. Basically it's a subarray the from the above problem it will be 5/1 it will automatically returns the size of array =5.

Sharilyn answered 14/10, 2020 at 14:21 Comment(2)
Why do you think sizeof(arr[0]) is 1? There's no implementation I know of for C++ where int is ever a single byte.Rigorism
As mentioned above, the sizeof operator is giving the size of a variable in bytes. Thus, sizeof(arr) is 10 * sizeof(int) in this case, and sizeof(int) is machine depended, and isn't 1 (either 2 or 4). Thus, we want to divide the size of the entire array in the size of a single variable in that array, therefore, we use the / sizeof(arr[0]) part.Occam
I
-3

The difference is int arr[5] = {1,2,3,4,5}; here arr is Pointer to array and &arr[0] is pointer of type Integer

Individualism answered 7/10, 2021 at 1:47 Comment(1)
There are many good answers to this question already. Your answer does not match the question completely and does not add anything new. Please read How to Answer questionsUnivalent

© 2022 - 2024 — McMap. All rights reserved.