Trying to assign an object to an array index

Hi there -

it doesn't like this code. Compiler says 'sensorArray' does not name a type. What am I doing wrong?

Thanks!

GoB_Sensor mySensor;

GoB_Sensor sensorArray[1];

sensorArray[0] = &mySensor;

Where in your sketch do those statements appear, in particular the third one ?

You can only assign a value to a previously declared variable inside a function. What you appear to be doing is the equivalent of this

int myArray[1];
myArray[0] = 123;

void setup()
{
    Serial.begin(115200);
}

void loop()
{
}

This code fails for the same reason as yours. Move the assignment of the value to the array into setup()

Can you see why posting just a fragment of a sketch is not helpful ?

1 Like

They are one after another, together. They are in the global area outside of setup and loop. I'd prefer the array be global. Is there some reason why arrays can't be initialized as global like this?

Last time I posted all the code, people got distracted in side quests, lol. Was not helpful.

1 Like

You could always post a small but complete sketch that illustrates the problem in context

That is your problem

So it sounds like it should work as written. That's what is baffling me. Will work around it.

The array can be global and you could define its values when you declare it, like this

int myArray[] = { 123 };

void setup()
{
    Serial.begin(115200);
}

void loop()
{
}

or you could define them later in setup(). Your choice

No, no, no

Put the definition of the array contents in setup()

Oh I see. Will try that.

Thanks.

I had a need for an "array of objects/instances" concerning OLEDs. Here is how I solved it...

#include <U8g2lib.h>
// https://github.com/olikraus/u8g2                    // library
// https://github.com/olikraus/u8g2/wiki/u8g2reference // reference
// https://github.com/olikraus/u8g2/wiki/fntlistall    // fonts

U8G2_SSD1306_128X64_NONAME_F_SW_I2C display[] = {
  // create an array of U8G2 objects
  U8G2_SSD1306_128X64_NONAME_F_SW_I2C(U8G2_R0, SCL, SDA, U8X8_PIN_NONE),  // first OLED
  U8G2_SSD1306_128X64_NONAME_F_SW_I2C(U8G2_R0, SCL, SDA, U8X8_PIN_NONE)   // second OLED
};

void setup() {
  configOled(0, 0x7A, u8g2_font_squeezed_b7_tr);  // address 0x7A = 0x3C
  configOled(1, 0x78, u8g2_font_t0_14b_mf);       // address 0x78 = 0x3D

  displayOled(0, 0, 7, "DISPLAY");
  displayOled(1, 0, 0, "display");
}

void loop() {
}

void configOled(int number, int address, const uint8_t* font) {
  display[number].setI2CAddress(address);
  display[number].begin();
  display[number].setFont(font);
  display[number].setDrawColor(1);  // white
  display[number].clearDisplay();
  display[number].clearBuffer();
  display[number].sendBuffer();  // transfer internal memory to the display
}

void displayOled(int number, int x, int y, const char* text) {
  display[number].setFontDirection(number);
  // display[number].setDisplayRotation(U8G2_R1); // only works with #define U8G2_Rx
  display[number].setCursor(x, y);
  display[number].print(text);
  display[number].print(number);
  display[number].sendBuffer();
  display[number].clearBuffer();  // must clear buffer for next display
}

you probably want an array of pointers

GoB_Sensor mySensor;
GoB_Sensor* sensorArray[1];
sensorArray[0] = &mySensor;

Incidentally, this declares an array with a single element, might work ok for testing but sort of senseless in real code.

Will that work outside of a function ?

no of course not - as you said

i was just giving the syntax.

(best of course probably would be to have directly the instance(s) in the array)

How about this

GoB_Sensor mySensor1, mySensor2, mySensor3;
GoB_Sensor sensorArray[] = {mySensor1, mySensor2, mySensor3 };
constexpr int noOfSensors = sizeof(sensorArray)/sizeof(sensorArray[0])

It's more or less the same as @xfpd did for the OLEDs ...

What you wrote is valid C++ but might not be what's intended.

When mySensor1, mySensor2, and mySensor3 are declared, their default constructors are called immediately. Then, sensorArray is created as a separate array of GoB_Sensor objects, and each element of sensorArray is copied from the corresponding object (mySensor1, mySensor2, mySensor3) using the copy constructor. So you end up with six objects in total: three originals and three copies inside the array.

If GoB_Sensor has no user-defined copy constructor, the compiler generates a default member-wise copy. Any modifications to sensorArray[i] do not affect mySensor1, mySensor2, or mySensor3.

Thanks for clarification. So it depends on the implementation of the object ...

I have quickly created an example that demonstrates the separate declaration, the declaration of an array of objects and also your suggestion (assignment of a pointer to the object(s) in setup()) to overcome this issue:

/*
   Forum: https://forum.arduino.cc/t/trying-to-assign-an-object-to-an-array-index/1424700
   Wokwi: https://wokwi.com/projects/452877818267674625

   ec2021

*/

class Dummy {
   private:
     byte value;
   public:
   Dummy(byte v): value(v){};
   byte getValue(){return value;};
};

Dummy test1(1),test2(2),test3(3);
Dummy testB[] = {test1, test2, test3};
constexpr int noOfTests = sizeof(testB)/sizeof(testB[0]);

Dummy* testX[noOfTests];

void setup() {
  Serial.begin(115200);
  testX[0] = &test1;
  testX[1] = &test2;
  testX[2] = &test3;
  Serial.println("Separate Objects");
  Serial.print(test1.getValue());
  Serial.print('\t');
  Serial.print(test2.getValue());
  Serial.print('\t');
  Serial.println(test3.getValue());
  Serial.println("Array in Declaration");
  for (int i=0;i<noOfTests;i++){
    Serial.print(testB[i].getValue());
    Serial.print('\t');
  }
  Serial.println("\nAssignment in Setup");
  for (int i=0;i<noOfTests;i++){
    Serial.print(testX[i]->getValue());
    Serial.print('\t');
  }
  Serial.println();
}

void loop() {
  // put your main code here, to run repeatedly:

}

Also on Wokwi: https://wokwi.com/projects/452877818267674625

EDIT: But this would work, wouldn't it?

Dummy* testY[noOfTests] = {&test1, &test2, &test3};

If you want an array of the actual instances of the object, instead of pointers

Dummy testB[] = {Dummy(1), Dummy(2), Dummy(3)};

There is no way to avoid duplication while still using an array of objects by value; duplication is intrinsic to arrays of objects.

Understood (finally) ... :- :wink:

The assignment in my "Edit" should make sure to get a pointer to the previously declared object, ok?

You are trying to assign apples to oranges
DwLaDe - Online C++ Compiler & Debugging Tool - Ideone.com this works