I'm really puzzled right now by what's happening when I declare an empty array with N elements. Every time I check the size of the array, it has twice as many elements as I declared in it. Also, when the values of an array are not initialized, should I find a random number in there? Below is my code, followed by the output:
void setup(){
Serial.begin(9600);
int num_of_elements = 10;
int myarray[num_of_elements];
delay(3000);
int sizeA = sizeof(myarray);
Serial.print("myarray has a size of ");
Serial.println(sizeA);
int r;
for(r=0;r<sizeof(myarray);r++)
{
Serial.print("Element ");
Serial.print(r);
Serial.print(" = ");
Serial.println(myarray[r]);
}
}
void loop(){}
Output:
myarray has a size of 20
Element 0 = 2816
Element 1 = -504
Element 2 = -3832
Element 3 = 512
Element 4 = 2145
Element 5 = 241
Element 6 = 4574
Element 7 = 2053
Element 8 = -81
Element 9 = 29696
Element 10 = 104
Element 11 = -8704
Element 12 = 1297
Element 13 = -3839
Element 14 = -17917
Element 15 = 26624
Element 16 = 23296
Element 17 = 31085
Element 18 = 29281
Element 19 = 24946
I didn't think it could have 20. I was confused when I went to print each element in a loop and got 20 numbers back. Why is it returning a value when I call an element that is out of it's index?
void setup()
{
Serial.begin(115200);
int myarray[10];
Serial.print("myarray takes this number of bytes ");
Serial.println(sizeof(myarray));
int sizeOfEachElement = sizeof(myarray[0]);
int numberOfElements = sizeof(myarray) / sizeOfEachElement;
Serial.print("myarray has this number of elements ");
Serial.println(numberOfElements);
}
void loop()
{
}
smahoo:
I'm really puzzled right now by what's happening when I declare an empty array with N elements. Every time I check the size of the array, it has twice as many elements as I declared in it. Also, when the values of an array are not initialized, should I find a random number in there? Below is my code, followed by the output:
sizeof() tells you how many BYTES are used by the array. A char or uint8_t array will have the same "sizeof()" as it's elements.
But, an array of int or uint16_t will have 2X the size of it's elements because each element has 2 bytes in it!
#define elementCount(x) (sizeof(x) / sizeof(x[0])
// ...some code...
int myarray[10];
for (int i = 0; i < elementCount(myarray); i++) {
// ...loop code...
}
// ...more code...
The macro takes the memory space allocated to the object and divides it by the size of one element in the object. The result is the number of elements in the object. This has the advantage of automatically adjusting the element count anytime you alter the array size.
When accessing elements for sure, you can be as dangerous as you like, however an array is not quite a pointer ;), Only the raw array name resolves to a pointer to the first element.
Standard indices are of type size_t, so there is no negative indices, just dangerous use of variable overflow.
The compiler maintains the index information as you can see with the template. It doesn't just guess the value of N, which shows it does care, very much.
More importantly, by using a template it should be clear that Arduino is C++, not C
I'd believe that if I hadn't seen it work on a processor with a signed address space, where RAM was in a very negative address range.
Uh huh, got any documentation.
Signed values used in conjunction with unsigned values are converted to unsigned.
The processor you used either wasn't programmed in C++, or is a non-standard version of the language, and could therefore do anything. size_t is unsigned set by the standard, which is tied to sizeof.
for (int i = 0; i < elementCount(myarray); i++) {
// ...loop code...
}
// ...more code...
The macro takes the memory space allocated to the object and divides it by the size of one element in the object. The result is the number of elements in the object. This has the advantage of automatically adjusting the element count anytime you alter the array size.
I'd believe that if I hadn't seen it work on a processor with a signed address space, where RAM was in a very negative address range.
Uh huh, got any documentation.
Signed values used in conjunction with unsigned values are converted to unsigned.
The processor you used either wasn't programmed in C++, or is a non-standard version of the language, and could therefore do anything. size_t is unsigned set by the standard, which is tied to sizeof.
That's a good point; C++ wasn't so common back then, and the only sensible options on the processor family were C (where negative indices were used to some effect) and occam, which of course, had bounded arrays and didn't have pointers.
I believe the architecture, sans links, lived on in one of ST's embedded processor families, so it would surprise me if C++ wasn't available some time.