After searching for a quite long while over the internet, I have no choice but to try asking someone if they can explain me this apparently strange situation.
I'm doing some tests using some servo motors, trying to move them almost together using millis()
and Servo
object.
It is, of course, working either for single Servos and multiple servos.
The case, more detailed, is about this:
- Move one, two or more servo motors together.
- Force them to take ALMOST the same time to accomplish any action.
- Have a dynamic number of servos.
About the first two points I had no problems to solve them, I was easily able to make a function and then make a library to accomplish such a job.
However, since I'm NOT that used to C++ and I was wondering if it actually was possible to create an array of Servo objects, like you can actually do, on arduino, with strings:
String stringArray[] = {"string1", "string2", "and so on, I love it."};
So, after wondering a while, I've tried this:
Servo servObject;
Servo servObject_2;
Servo servObject_3;
Servo servos[] = {servObject, servObject_2, servObject_3};
And you know what's cool? my function is actually working correctly by forcing the amount of elements of the servos array.
What I mean by that is that if I force my function to know that it is going to have 3 elements into the array it will, of course, work; However, for some reason, if I use sizeof(servos);
the value returned, surprisingly, is 2
....
Moreover, if I only push two servo objects instead of three into the servo array, its sizeof
returns 6
.
By googling, I've found out a couple of discussions about the fact that, for some reasons, in some cases, sizeof returns an incorrect value (if I'm not wrong it was the correct value -1), but in my case it apparently is not following any logic at all.
The board I'm using is an Arduino nano w/ ATMEGA 328.
Any idea of why it is not returning the correct value? Am I actually going totally wrong because I shouldn't make an array of servo objects?
ps: I didn't post the whole code because it would've been useless, since the sizeof is the first function called in the loop()
Regards,
briosheje
1 Answer 1
What you describe seems to be a common issue that many C or C++ developers can get (or have got) with sizeof
.
Take a look at the following code:
char a[3];
int size(char b[]) {
return sizeof b;
}
void setup() {
int size1 = sizeof a;
int size2 = size(a);
}
In that code, size1
will be evaluated, by the compiler, to 3
which is the real size of a
variable, whereas size2
will be 2
.
Why so?
This is just because sizeof a
is evaluated by the compiler, and the compiler knows that a
is an array of 3 char
; but when a
is passed as an argument to function size()
, it is converted to a pointer (to the first element of the array), hence its size is the size of a pointer, which is 2
bytes on AVR ATmega MCU.
This subtlety of sizeof
may explain strange values as you describe.
How to fix the issue?
Most C functions that take an array as argument will require another argument that tells the size of the array; that's the way (the only one I think) to deal with this problem.
Here is a sample code:
Servo allServos[] = {...};
#define NUM_SERVOS (sizeof(allServos) / sizeof(Servo))
...
void handleServos(Servo *servos, int numServos) {
for (int i = 0; i < numServos; i++) {
servos[i].write(...);
...
}
}
void loop() {
handleServos(allServos, NUM_SERVOS);
}
It is common practice in C to declare an array and immediately after, define its size as above.
-
Oh, thanks, I didn't know that sizeof, in that case, would have refered to the pointer of the Array. So, is there any way to get the true size of the above array of Servo objects? Am I supposed to count each element and use a counter?briosheje– briosheje2014年05月07日 21:01:30 +00:00Commented May 7, 2014 at 21:01
-
@briosheje see the latest edit to my answer.jfpoilpret– jfpoilpret2014年05月07日 21:11:49 +00:00Commented May 7, 2014 at 21:11
-
Thanks! It works! :) I've already confirmed the answer as solution but still, thanks for the clear explanation!briosheje– briosheje2014年05月07日 21:25:59 +00:00Commented May 7, 2014 at 21:25
sizeof
construct available for any array object. Therefore, any array (ex. int elements[] = {2,3,1,3,9};) outputs its correct value (in the previous case 5) and I'm getting the value directly from the Serial port. In any case, tonight, I will upload the whole code, I'm not and home and can't really paste it from my Nexus 5 :Psizeof
at the start of my loop, it still outputs the same value as in the function where I'm using it. Also, is there any alternative to check if an array element exists? If it's possible, then I could make my ownsizeof
prototype.#define countof(a) (sizeof(a)/sizeof(a[0]))
to find the # of elements in an array, but since it depends onsizeof()
it's won't be much help to you.