define array size when class or struct is declaired?

so if i have a class that has an array inside of it. how can the size of the array be declared when the user declares the class?

this code doesn't work. there must be some way or work around for this.

class myclass {

public:
byte arr [];
myclass(int size){ arr[size]; }
};



myclass m(10);

Dynamic memory allocation would be one way, template would be another one.

Have a look at the arduino JSON library and how Benoît approached it:

You can choose to store data in the stack:StaticJsonDocument<256> doc;or on the heapDynamicJsonDocument doc(256);

taterking:
so if i have a class that has an array inside of it. how can the size of the array be declared when the user declares the class?

this code doesn't work. there must be some way or work around for this.

class myclass {

public:
byte arr [];
myclass(int size){ arr[size]; }
};

myclass m(10);

I have been advised repeatedly that using dynamic memory on an Arduino is BAD!

Due to memory fragmentation when the sketch runs continuously for days, weeks and months....leading to a program crash and burn.

So a template class would be the best approach IMHO.
See attached if you want an example.

LongTimer.cpp (88 Bytes)

LongTimer.h (6.57 KB)

Dynamic allocation is challenging (can lead to heap fragmentation ) if you keep allocating and freeing in random ways. If you just instantiate your class and the object sticks for the duration of the program then you have no issue (as long as all fits in memory)

What’s your use case ?

taterking:
so if i have a class that has an array inside of it. how can the size of the array be declared when the user declares the class?

this code doesn't work. there must be some way or work around for this.

class myclass {

public:
byte arr [];
myclass(int size){ arr[size]; }
};

myclass m(10);

you should heed the advice given by the other posters but if you really wanted to do it...

In C++ you can do:

int *array; // declare a pointer of type int.
array = new int[someSize]; // dynamically allocate memory using new

and once you are done using the memory..de-allocate it using delete as:

delete[]array;

so in your example then it would be probably something like this:

class myclass {

public:
byte *arr;
myclass(int size){ arr = new byte[size]; }
~myclass(){ delete[]arr; }
};

sorry i left out the fact that i am looking to create an array of my class!

i am comming into arduino from c#.

i defiantly do not need my array inside the class to be dynamic. the way that i understand the term "dynamic" is that it is adjustable. i want to set a fixed size on declaration and was hoping there would be a way in c++ to ask for the set reservation of memory at the top of my sketch.

another option i was considering was to give each class a reference to a jagged array.

something like this:

byte jagged [][]= {{1,2,3},{1,2,3,4},{1,2,3,4,5}};

but c++ is not undersanding a jagged array either.

so to accomplish my task i see no other option but something messy and ugly like this:

class myclass {
  public:
  static byte store [11]{1,2,3,1,2,3,4,1,2,3,4,5};
  static byte returnarray [5];//highest number declaired
  byte myindex;
  byte mylength;
  void fill (){
   
    byte i = mylength;
    while(i>0){i--;
    returnarray[i]=store[i+myindex]; } }
    myclass(byte idx, byte len){
    myindex = idx; mylength = len;

    // will need to grab from the return array and use the classes length variable
    }
  
  };

for my purposes i will need to loop through many instances of the class and the array size can vary alot so i dont want to reserve memory for the max amount that each class would have.

You did not answer on the lifespan of your instances. Also are they allocated dynamically based on dynamic information at run time or do you know how many you need and their size?

I’m still unclear why you are ruling out dynamic allocation?

nothing need to change in runtime. i was just hoping i could declair the different array sizes at the top of my sketch. i dont want to list them individually because i will need to loop through them in nested loops.

I don’t see what prevents you from doing so

the instances would have to remember how big is their array, so then just ask the target object in your loops

taterking:
so if i have a class that has an array inside of it. how can the size of the array be declared when the user declares the class?

this code doesn't work. there must be some way or work around for this.

class myclass {

public:
byte arr [];
myclass(int size){ arr[size]; }
};

myclass m(10);

Simplest way is put a pointer to byte in your class and fill that with a pointer to an array when you initialize.

I lost a lot of my C++ knowhow in 2000 so I'm a bit fuzzy here but

byte arr[]; // might compile a pointer to NULL that you could overwrite with a pointer to data.

PS, also it's

myclass m[ 10 ]; // to make an array of class objects

With limited RAM and different classes/structs that you want to use not all at the same time, you can share space in a buffer that will hold all you do want to use.

Instead of declaring class/struct objects, declare pointers to them and point inside of the buffer to where the data goes. You get class->data access (instead of class.data) but it's all there including the functions. And yes, the pointers take 2 bytes each so decide if it's worth the flexibility first.

That kind of here now, gone later dynamic does work. I first did a version of this with Basic long before I knew C. Maybe I did something horrible in a past life that I had to write so much Basic.

here is an example on how you could dynamically allocate the array's memory in the class.

I've put two ways of doing so:

1/ create an array (2 dimensions for the fun) of instances of the class with array size defined with numbers known when you write the code
2/ create a similar array of instances but the array size is calculated at run time.

class DemoClass
{
  public:
    // instance variables
    uint8_t myArraySize;
    uint8_t* myArray;

    // constructor
    DemoClass(uint8_t aSize) : myArraySize(aSize) {
      if (aSize != 0) myArray = (uint8_t*) malloc(aSize);
      else myArray = NULL;
      if (myArray != NULL) {
        // initialize array with every value at the size (why not :-))
        for (uint8_t anIndex = 0; anIndex < myArraySize; anIndex++) myArray[anIndex] = myArraySize;
      } else myArraySize = 0; // in case malloc failed
    }

    // destructor
    ~DemoClass() {
      if (myArray != NULL) free(myArray);
      myArray = NULL;
      myArraySize = 0;
    }

    void printArray() {
      for (uint8_t anIndex = 0; anIndex < myArraySize; anIndex++) {
        Serial.print(F("  myArray["));
        Serial.print(anIndex);
        Serial.print(F("] = "));
        Serial.println(myArray[anIndex]);
      }
    }
};

const uint8_t nbRow = 2, nbCol = 3;

DemoClass myObjectsStatic[nbRow][nbCol] = { // HERE WE USE KNOWN SIZE NUMBERS FOR THE ARRAY
  {DemoClass(1), DemoClass(2), DemoClass(3)},
  {DemoClass(4), DemoClass(5), DemoClass(6)},
};

DemoClass* myObjectsDynamic[nbRow][nbCol];


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

  // print out the statically created objects
  Serial.println(F("\n\n----- DIMENSIONS ALLOCATED AT COMPILE TIME ------\n\n"));

  for (uint8_t r = 0; r < nbRow; r++)
    for (uint8_t c = 0; c < nbCol; c++) {
      Serial.println(F("-------------------------"));
      Serial.print(F("myObjectsStatic["));
      Serial.print(r);
      Serial.print(F("]["));
      Serial.print(c);
      Serial.print(F("] array has "));
      Serial.print(myObjectsStatic[r][c].myArraySize);
      Serial.print(F(" element"));
      if (myObjectsStatic[r][c].myArraySize > 1) Serial.println(F("s"));
      else Serial.println();
      myObjectsStatic[r][c].printArray();
    }

  Serial.println(F("\n\n----- DIMENSIONS COMPUTED AT RUN TIME ------\n\n"));

  // instantiate the dynamic elements
  for (uint8_t r = 0; r < nbRow; r++)
    for (uint8_t c = 0; c < nbCol; c++)
      myObjectsDynamic[r][c] = new DemoClass((r + 1) * (c + 1)); // here array dimension is calculated at run time

  // print out the dynamically created objects
  for (uint8_t r = 0; r < nbRow; r++)
    for (uint8_t c = 0; c < nbCol; c++) {
      Serial.println(F("-------------------------"));
      Serial.print(F("myObjectsDynamic["));
      Serial.print(r);
      Serial.print(F("]["));
      Serial.print(c);
      Serial.print(F("] array has "));
      Serial.print(myObjectsDynamic[r][c]->myArraySize);
      Serial.print(F(" element"));
      if (myObjectsDynamic[r][c]->myArraySize > 1) Serial.println(F("s"));
      else Serial.println();
      myObjectsDynamic[r][c]->printArray();
    }
  Serial.println(F("-------------------------"));

}

void loop() {}

if you set your console at 115200 bauds, you should see something like this:

[color=blue][b]----- DIMENSIONS ALLOCATED AT COMPILE TIME ------[/b]


-------------------------
myObjectsStatic[0][0] array has 1 element
  myArray[0] = 1
-------------------------
myObjectsStatic[0][1] array has 2 elements
  myArray[0] = 2
  myArray[1] = 2
-------------------------
myObjectsStatic[0][2] array has 3 elements
  myArray[0] = 3
  myArray[1] = 3
  myArray[2] = 3
-------------------------
myObjectsStatic[1][0] array has 4 elements
  myArray[0] = 4
  myArray[1] = 4
  myArray[2] = 4
  myArray[3] = 4
-------------------------
myObjectsStatic[1][1] array has 5 elements
  myArray[0] = 5
  myArray[1] = 5
  myArray[2] = 5
  myArray[3] = 5
  myArray[4] = 5
-------------------------
myObjectsStatic[1][2] array has 6 elements
  myArray[0] = 6
  myArray[1] = 6
  myArray[2] = 6
  myArray[3] = 6
  myArray[4] = 6
  myArray[5] = 6[/color]


[color=purple][b]----- DIMENSIONS COMPUTED AT RUN TIME ------[/b]

-------------------------
myObjectsDynamic[0][0] array has 1 element
  myArray[0] = 1
-------------------------
myObjectsDynamic[0][1] array has 2 elements
  myArray[0] = 2
  myArray[1] = 2
-------------------------
myObjectsDynamic[0][2] array has 3 elements
  myArray[0] = 3
  myArray[1] = 3
  myArray[2] = 3
-------------------------
myObjectsDynamic[1][0] array has 2 elements
  myArray[0] = 2
  myArray[1] = 2
-------------------------
myObjectsDynamic[1][1] array has 4 elements
  myArray[0] = 4
  myArray[1] = 4
  myArray[2] = 4
  myArray[3] = 4
-------------------------
myObjectsDynamic[1][2] array has 6 elements
  myArray[0] = 6
  myArray[1] = 6
  myArray[2] = 6
  myArray[3] = 6
  myArray[4] = 6
  myArray[5] = 6
-------------------------
[/color]