Array Length

How can the Arduino know how long an array is?

I need to pass an array (actually a pointer to an array) to a function, and the function needs to be able to determine how many elements the array contains. I think I want something like strlen, but for a uint8_t array (no NULL character guaranteed).

You give another parameter to the function that's the length. Or you terminate the array with a unique value.

Thanks for the reply.

Neither of those are ideal, but probably possible.

Are there other options?

mattallen37:
Thanks for the reply.

Neither of those are ideal, but probably possible.

Are there other options?

no, not really. If you're passing an array anyway, might as well pass the length. After all, when you pass an array it just says "the memory you want is here:" That's it, so your options are limited.

You could also make something like there is in java:

template<class T, size_t len> struct ary {
  T& operator[](size_t i) { return data[i]; }
  size_t length;
  T data[len];
};

Pass a struct containing the pointer and the length? Not substantially different to passing the length separately.

You can use the Standard Template Library and pass a vector. That has its pluses and minuses. By far the simplest is just to pass the array and its length as two arguments.

mattallen37:
Thanks for the reply.

Neither of those are ideal, but probably possible.

Are there other options?

Create a class with pointer and length (like the String class), and just pass references to the class. The class would have an argument for the array size.

The C language specifies that when you pass an array to a function, it is converted to a pointer to the first element, so the length information is not passed. Other languages might have this feature, but C does not not.

PeterH:
Pass a struct containing the pointer and the length? Not substantially different to passing the length separately.

Well of course it isn't -- otherwise, it wouldn't work!

Might as well make 'length' static as the class and array are bound to it.

template<class T, size_t len> struct ary {
  T& operator[](size_t i) { return data[i]; }
  enum{ length = len };
  T data[length];
};

//...
ary< int, 4 > a = { 0, 1, 2, 3 };

//..
Serial.print( "Len: " );
Serial.println( a.length );

Also, with a conversion operator it now behaves exactly like an array when passed to functions expecting a pointer. ( would be unsafe if 'length' was not a constant. )

template<class T, size_t len> struct ary {
  T& operator[](size_t i) { return this->data[i]; }
  operator T*(){ return this->data; }
  enum{ length = len };
  T data[length];
};

//...
ary< char, 4 > a = { 'a', 'b', 'c', '\0' };

//...
Serial.print( a );

EDIT: Also, as it mixes dependant & non-dependant names 'this->' should be used to prevent global non-dependant names from resolving.

Delta_G:
http://arduino.cc/en/Reference/Sizeof

Doesn't work? Is that because it is being passed as an argument to the function?

No. As I said earlier, when you pass the array to a function, it is converted to a pointer to the first element. This means in the caller when the compiler knows it is an array, sizeof returns what you expect (size of each element times the number of elements). Inside the function, sizeof returns the size of a pointer (2 bytes in the case of the Arduino, 4 bytes on 32-bit systems, 8 bytes for 64-bit systems).

Could modify the class version I posted with this enum.

enum{ 
	length = len,
	size = sizeof( T ) * len
};

//Then code like this would work.
Serial.println( a );
Serial.println( a.length );
Serial.println( a.size );

sizeof()
This operator accepts one parameter, which can be either a type or a variable itself and returns the size in bytes of
that type or object:
a = sizeof (char);
This will assign the value 1 to a because char is a one-byte long type.
The value returned by sizeof is a constant, so it is always determined before program execution.

Text above was copied from: http://www.cplusplus.com/doc/tutorial/

It seems that sizeof() is an operator, not a function, and is only evaluated at compile time and not at run time. This is for C++.

Thanks all for you ideas.