Go Down

Topic: dynamische array erweiterung in einer struktur. (Read 117 times) previous topic - next topic

mysource

Hallo,

Ich habe zwei typedef struct, ein INDEX und ein SUB-INDEX. Wie unten zu sehen ist, ist recordSubIndex als array mit der Grösse 5 deklariert. Während der Runtime kann es aber sein dass dieses Array erweitert werden muss, da 5 nicht genügend Platz bietet.  Wie kann cih am einfachsten dieses Array erweitern?

Code: [Select]
typedef struct {
  uint8_t subIndex;
  String description;
  ACCESS access;
  PDO_MAPPING pdoMapping;
  OD_DATA_LEN_t datalength;
  uint8_t data[8];
  uint32_t defaultValue;
} OD_subIndex;


typedef struct {
  uint16_t index;
  String name;
  uint8_t minSubIndices;
  uint8_t maxSubIndices;
  uint8_t initSubIndices;
  OD_subIndex recordSubIndex[5];
} OD_index;


Habe gegoogelt und ein paar vorschläge gesehen.. die, wenn ich sie umsetze, bei mir nicht funktionieren.


Code: [Select]
// die alte grösse des arrays ermitteln
uint8_t oldSize = sizeof(recordIndex[index].recordSubIndex) / sizeof(recordIndex[index].recordSubIndex[0]);
// neues Array mit der neuen Grösse erstellen
uint8_t *temp = new uint8_t[newSize + 1]; // +1 for sub-index 0x00
// kopieren des alten Arrays ins temporöre Array
memcpy(temp, recordIndex[index].recordSubIndex, oldSize);
// löschen des alten arrays
delete [] recordIndex[index].recordSubIndex;
// zuweisen des neuen Arrays...
recordIndex[index].recordSubIndex = temp;



--> delete [] recordIndex[index].recordSubIndex; funktioniert nicht, der ATmega2560 krascht hier.

hat jemand eine idee wie ich dieses Problem lösen kann?








uwefed

Indem Du das Array am Anfang groß genug machst.
Grüße Uwe

DrDiettrich

Kommt drauf an, welchen Controller Du verwendest. Auf einem 8 Bit ATmega hat Uwe völlig recht, da sollte man keine dynamischen Arrays benutzen, nicht einmal den Typ String. Auf größeren Controllern sollte die dynamische Speicherverwaltung besser funktionieren. Ich habe allerdings bislang nur mit alloc/realloc gearbeitet, was im Detail auf welchem Controller funktioniert kann ich nicht sagen.

ElEspanol

Wie lange soll denn das „erweiterte" Array existieren?
Wann und kommt der Fall vor?
Welcher uC?

MicroBahner

Zum einen: Wenn Du das Array zunächst statisch angelegt hast, kannst Du es nicht hinterher mit delete freigeben. Das geht nur mit Speicher, der von vornherein dynamisch angelegt ist.

Zum anderen: Wenn dein Ram groß genug ist, um den erweiterten Platzbedarf aufzunehmen, kannst Du ihn auch direkt so groß machen. Wenn es nicht groß genug ist, funktioniert es auch hinterher dynamisch nicht.

Die dynamische Speicherverwaltung macht nur Sinn, wenn Du an verschiedenen Stellen mal hier, mal da Speicher brauchst, aber nie gleichzeitig. Bei wenig Ram macht es eher Ärger, weil durch die Speicherverwaltung und das ständige Anfordern/Freigeben der Speicher fragmentiert wird, und dadurch von dem eh schon knappen Speicher Teile nicht mehr genutzt werden können. Eine 'Garbage Collection', die sowas wieder bereinigt, gibt es - zumindest auf den Standard-Arduinos - nicht.
Gruß, Franz-Peter

mysource

#5
Oct 21, 2019, 03:30 pm Last Edit: Oct 21, 2019, 03:38 pm by mysource
Danke für eure Antworten.

Es handelt sich hier um einen Aufbau eines ObjectDirectorys aus CANopen.

@uwefed
klar könnte ich das Array auf die maximale Anzahl der sub-indexes erstellen, dies sind 256, natürlich nicht bei allen objekten im OD aber das können einige sein, und aus meiner Sicht ist das absolute verschwendung des Speichers wenn man sie dann sowieso nicht benutzt.

Die Arrays sind solange gültig wie der µC läuft, oder in speziellen Fällen das Object respektive, die sub-indexe existieren.


Zum einen: Wenn Du das Array zunächst statisch angelegt hast, kannst Du es nicht hinterher mit delete freigeben. Das geht nur mit Speicher, der von vornherein dynamisch angelegt ist.

Zum anderen: Wenn dein Ram groß genug ist, um den erweiterten Platzbedarf aufzunehmen, kannst Du ihn auch direkt so groß machen. Wenn es nicht groß genug ist, funktioniert es auch hinterher dynamisch nicht.

Die dynamische Speicherverwaltung macht nur Sinn, wenn Du an verschiedenen Stellen mal hier, mal da Speicher brauchst, aber nie gleichzeitig. Bei wenig Ram macht es eher Ärger, weil durch die Speicherverwaltung und das ständige Anfordern/Freigeben der Speicher fragmentiert wird, und dadurch von dem eh schon knappen Speicher Teile nicht mehr genutzt werden können. Eine 'Garbage Collection', die sowas wieder bereinigt, gibt es - zumindest auf den Standard-Arduinos - nicht.
OK, macht durchaus Sinn.

Ich werde diese Arrays mal so anlegen.

Besten Dank für euer Feedback.

Go Up