4

I've the following C++ array:

byte data[] = {0xc7, 0x05, 0x04, 0x11 ,0x45, 0x00, 0x00, 0x00, 0x00, 0x00}; 

How can I know how many items there are in this array?

2
  • What do you want the answer be in the case you gave? 5 or 10? Commented Jan 16, 2010 at 11:06
  • 10 (I hate the 15 limit on comments) Commented Jan 16, 2010 at 11:29

3 Answers 3

10

For byte-sized elements, you can use sizeof(data).

More generally, sizeof(data)/sizeof(data[0]) will give the number of elements.


Since this issue came up in your last question, I'll clarify that this can't be used when you pass an array to a function as a parameter:

void f(byte arr[]) { //This always prints the size of a pointer, regardless of number of elements. cout << sizeof(arr); } void g() { byte data[] = {0xc7, 0x05, 0x04, 0x11 ,0x45, 0x00, 0x00, 0x00, 0x00, 0x00}; cout << sizeof(data); //prints 10 } 
Sign up to request clarification or add additional context in comments.

3 Comments

Note that this will only work when the array definition is being seen by the compiler (that is either the array is global or within the same function). It will fail if the array is passed as argument to a function, and it will fail silently providing an erroneous answer. int f( char data[] ) { return sizeof(data)/sizeof(data[0]); } void caller() { char array[] = { 0 }; f(array) } will return the size of a pointer (usually 4/8) and not 1, which is the actual solution. This is because arrays decay into pointers at function calls when passed by value.
Tip: it's common to define a macro like this: #define ARRSIZE(arr) (sizeof(arr)/sizeof(*(arr))) to get the number of elements of an array whose size is known at compile time.
"this can't be used when you pass an array to a function" ... It can when using references.
5

You should really use Neil's suggestion: std::vector<byte> is a much better solution in most cases (the only more complex part is initialization, on anything else it is safer).

If not, instead of using the sizeof(array)/sizeof(array[0]), or sizeof(array) (since sizeof(byte)==1), you can use a typesafe approach with templates:

template <typename T, unsigned int N> unsigned int size_of_array( T (&)[N] ) { return N; } 

Or, if you need a compile time constant (and at the same time you want to make sure you do not accidentally call it on non-arrays:

template <typename T, unsigned int N> char (&static_size_of_array( T (&)[N] ))[N]; #define compile_time_size(x) (sizeof(static_size_of_array((x)))) 

In most cases you will not need that last solution. Both templated solutions will fail fast when a pointer is passed (instead of an array):

void f( char array[] ) // misleading name: { char array2[] = { 1, 2, 3 }; size_of_array(array2); // 3 size_of_array(array); // compile time error sizeof(array)/sizeof(array[0]); // 4/8, depending on architecture!!! } 

Comments

2
sizeof( data); // because sizeof(byte) is 1 

However, this is not a good general solution - particularly if you pass the array to functions:

void f( byte a[] ) { // number of elements in 'a' unknown here } 

The array decays to a pointer, so the sizeof operator will always give you the size of the pointer, not the number of elements in the array.

Instead, you should use a std::vector<byte>, which has a size() member function.

3 Comments

"The array decays to a pointer" ... references fix that: template<size_t n> void f(byte (&a)[n])
So you have to provide the size as a compile time template parameter?
No, see e.g. here (self-plug, but fastest to find): stackoverflow.com/questions/1745942/… ... with references the full array type is preserved.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.