Size of an Array in C++: Count Elements Safely

Code example comparing std::size and sizeof on a built-in array

Use std::size(array) for a built-in array in C++17 and later. You can also divide sizeof(array) by sizeof(array[0]) while the compiler still knows the complete array type. Both methods return the number of elements, not the array’s size in bytes.

For example, a five-element array has a C++ array length of 5. The key limitation is array-to-pointer decay: after an array becomes a pointer, neither method can recover the original element count. This guide shows how to get an array’s size in C++ safely and when to use .size() instead.

Size of an Array in C++ with std::size: a five-element example

std::size is the clearest standard-library option for counting elements in a built-in array. Include <iterator>, then pass the array directly to the function. It returns the array’s element count as a size type, normally std::size_t.

Example: #include <cstddef>; #include <iterator>; int scores[] = { 12, 18, 24, 31, 40 };; std::size_t count = std::size(scores);. The value of count is 5.

The compiler determines the bound from the array type, which is int[5] in this example. You do not need to repeat the bound or maintain a separate constant. Unlike a member function, std::size works with a built-in array even though built-in arrays do not have a .size() member.

This overload preserves the array type by receiving it through a reference. That detail matters because passing the array in the wrong context can change it into a pointer before the count is calculated.

Use the C++ sizeof operator for an array: division returns 5

The traditional C++ sizeof for an array formula divides the total number of bytes occupied by the array by the number of bytes occupied by one element:

Formula: sizeof(array) / sizeof(array[0])

Applied to the same five-element array, the code is std::size_t count = sizeof(scores) / sizeof(scores[0]);. The result is 5. The numerator represents all five elements, while the denominator represents one int. The calculation therefore produces an element count regardless of the platform’s actual int size.

sizeof(scores) is not itself the array length. It reports the array’s total storage in bytes. Similarly, sizeof(scores[0]) reports the storage for one element. The division is valid only when scores still has its array type, such as in the same scope where it was declared or in a function that receives an array by reference.

std::size is usually preferable in modern C++ because it states the intent directly and avoids repeating the element expression. The sizeof formula remains useful in older language standards and in low-level code where the array type is known.

Why is C++ array size lost after array-to-pointer decay?

When a built-in array is passed to an ordinary function parameter, it normally changes, or decays, into a pointer to its first element. Bracket notation in a parameter does not prevent this adjustment. These declarations therefore describe the same effective parameter:

void report(const int values[]); and void report(const int* values);

Inside report, values is a pointer, not an array. Consequently, sizeof(values) returns the pointer’s storage size, while sizeof(values[0]) returns the size of one integer. Dividing those values produces an unrelated result rather than the original number of elements. The result may vary by platform and pointer type, so never apply the array division formula to a pointer.

std::size(values) also cannot count the original array in this function. Its array overload requires an actual array, and a pointer does not contain a record of how many elements were allocated or where the array ends. A pointer might refer to one element, a dynamically allocated block, or only a subrange of a larger array.

Pass the count separately when a function intentionally accepts a pointer:

void report(const int* values, std::size_t count);

Alternatively, accept the built-in array by reference so its bound remains available:

template <typename T, std::size_t N> constexpr std::size_t countOf(const T (&values)[N]) { return N; }

Calling countOf(scores) returns 5. The reference parameter prevents array-to-pointer decay, and N captures the bound at compile time.

How do std::array and std::vector report C++ array length? .size() returns the element count

std::array is a fixed-size container that keeps its element count as part of its type. Its .size() member returns the number of stored elements:

std::array<int, 5> fixedScores{ 12, 18, 24, 31, 40 };; fixedScores.size() returns 5.

The value cannot change during the lifetime of that std::array. An std::array<int, 0> is valid, and its .size() returns 0. Use this container when you want array-like storage with standard container interfaces, iterators, and a reliable size operation.

std::vector stores a variable number of elements. Its .size() member returns the number of elements currently stored, not the amount of memory reserved:

std::vector<int> dynamicScores{ 12, 18, 24, 31, 40 };; dynamicScores.size() returns 5. After dynamicScores.push_back(47), it returns 6. Use .capacity() only when you need the allocated storage capacity; it is not the C++ array length.