Hello forum, I have what I think is a simple question that is causing me unexpectedly large headaches.
I want to pass an array to a class. In my naive mind, an array is passed by passing (by value) a pointer to its first element. So, the idea goes, the elements of an array declared in a different scope, will be accessible to the methods of the class. The code below explodes:
class classy {
public:
int a1d[]; // this should end up pointing to the array myArray in setup()
classy(int passedArray[]) {
a1d = passedArray; // this is the line that blows up
}
};
void setup() {
int myArray[5] = { 0, 1, 2, 3, 4 };
classy c = classy(myArray);
}
void loop() {}
So, I need to make it so that a method in classy referring to, say, a1d[2] will access myArray[2].
However, I get the following error:
sketch_aug05c.cpp: In constructor ‘classy::classy(int*)’:
sketch_aug05c:7: error: incompatible types in assignment of ‘int*’ to ‘int [ 0 ]’
So, if I got that right, passedArray[] is considered an integer pointer (‘int*’, which is what I think a reference to an array is. Note that the constructor is referred to as ‘classy::classy(int*)’ whereas I have declared it as ‘classy(int passedArray[]’), which I guess amounts to the same thing) but a1d is considered the contents of the first element of an integer array (‘int [ 0 ]’)? Both are referred to in exactly the same way in the offending line. Am I going crazy or is the compiler linguistically challenged?
passedArray is a pointer to an array in memory (an "int *"). a1d is an empty array - a similar concept but not quite the same.
Define a1d as "int *a1d;" instead of "int a1d[];" and you can assign it the address of the incoming array.
NOTE
This does NOT copy the contents of the array - it merely points a1d at the same memory as passedArray. To copy the actual array you will have to manually copy either each entry in the array to a pre-created array of a large enough size, or duplicate the memory, which may lead to memory fragmentation and/or memory leaks.
I certainly don't want the array copied, I just want the object to have the address of the original array so it can access its elements.
One thing I 'd like to add for any poor guys struggling with similar. When stepping this up to 2D arrays, it gets slightly tricky due to operator precedence of * and []. The way to do it is this:
class classy {
public:
int (*a1d)[5]; // mind the ()
classy(int passedArray[][5]) {
a1d = passedArray;
Serial.print("CONSTRUCTOR:\nElement at [1][3] of passed array is "); Serial.println(a1d[1][3]); Serial.println("Now setting it to -1\n--------------");
a1d[1][3] = -1;
}
It's trying to make "a1d" refer to the same thing in "classy" as "myArray" refers to in setup() so that a1d[m][n] in "classy" will fetch me the same result (by reading the same address) as myArray[m][n] would in setup().
In the grander scheme of things, when this class grows up, it will be used to play tunes on a speaker. The object is pointed towards an array of notes and durations and handles the rest.
So far it's working with no obvious bugs but if you see any problems I 'd be grateful if you 'd point them out.