Dynamische Arraygröße mit malloc/calloc

Ich habe aktuell in einer Klasse einen Buffer/Array mit einer hartkodierten Größe von 64 Byte.
Eigentlich bräuchte ich den Buffer nur in der Größe 8 x numDevices wobei ich numDevices dem Constructor übergebe.

Meine Frage:
Wenn ich kein Template verwenden will, und die Objekte ohnehin nur Global angelegt werden, kann man dann gefahrlos malloc/calloc verwenden?
Einen Deconstructor mit free könnte man ja sicherheitshalber noch dazu geben:

in etwa so:

class Test
{
  protected:
    //uint8_t status[8 * 8]; // hardcoded Buffergröße soll ersetzt werden
    uint8_t numDevices;
    uint8_t *status;

  public:
    Test(uint8_t numDevices) :
      numDevices (numDevices)
    {
      status = (uint8_t*)calloc(8 * numDevices, sizeof(uint8_t));
    }
    
    ~Test()
    {
      free(status);
    }

    void set(size_t index, uint8_t content)
    {
      status[index] = content;
    }

    void debug()
    {
      for (size_t i = 0; i < numDevices; i++)
      {
        for (byte j = 0; j < 8; j++)
        {
          Serial.print(status[i*8+j]);
          Serial.print("\t");
        }
        Serial.println();
      }
    }
};

Test myObject(2);


void setup() {
  Serial.begin(115200);
  myObject.set(1, 1);
  myObject.set(2, 2);
  myObject.set(3, 3);
  myObject.set(4, 4);

  myObject.set(12, 4);
  myObject.set(13, 3);
  myObject.set(14, 2);
  myObject.set(15, 1);
  
  myObject.debug();
}

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

}

die Testausgabe macht was ich mir vorstelle:

0 1 2 3 4 0 0 0
0 0 0 0 4 3 2 1

Der Buffer liegt nun statt im static memory im heap, und im Static Memory(? oder doch am Stack?) halt der Pointer, aber damit kann man meines erachtens leben, jedenfalls sollten nicht mehr fix die 64 Byte verbraucht werden.

Oder gibts da Einwände?

Wenn ich kein Template verwenden will,

Was schade ist...

Wenn ich kein Template verwenden will, und die Objekte ohnehin nur Global angelegt werden, kann man dann gefahrlos malloc/calloc verwenden?

Die IDE zeigt nicht den wirklichen Verbrauch an.
Das ist der übelste Faktor.

Einen Deconstructor mit free könnte man ja sicherheitshalber noch dazu geben

Auf jeden Fall!
Wer Speicher reserviert, muss auch aufräumen. Destruktor also Pflicht
Zudem müsste man evtl auch auf die Copy und Zuweisungs- Operatoren/Konstruktoren achten.
Wer weiß, wer das in die Hand bekommt. (oder du selber damit anstellst)

Check' mal den Speicherbedarf der 64-Byte-Variante und den der "optimierten" :slight_smile:

ja sehe ich gerade, nachdem ich es in meiner Library eingebaut hätte. Geht gar nicht. Ist so nicht akzeptabel.

Bisher:
Sketch Version 2020-03-08 (6106 Flash / 341 Globals)

und nun
Der Sketch verwendet 6620 Bytes (20%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 289 Bytes (14%) des dynamischen Speichers, 1759 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.

F*ck ... das will ich auch nicht.
Ich glaub das werden wir wieder reverten...

Danke euch beiden.
Karma+