Gast
#5984090
Mein Programm hat ein Array von Objekten, die mit
1 | |
erzeugt wurden. Wie kann ich alle Objekte löschen, damit das Array mit neu erzeugten Objekten gefüllt werden kann?
|
Anzeige
|
C++ Mc gcc Object löschen
Gast
#5984090
Mein Programm hat ein Array von Objekten, die mit
erzeugt wurden. Wie kann ich alle Objekte löschen, damit das Array mit neu erzeugten Objekten gefüllt werden kann? Mit
Anders geht es nicht, auch wenn du vermutlich was anderes hören wolltest. Oliver P.S. Dein Code ist übrigens falsch
Gast
#5984112
>Anders geht es nicht, auch wenn du vermutlich was anderes hören >wolltest. Gibt's da keine Problem mit der Garbage Collection? Gibt es ein Delete auf einem STM32?
Gast
#5984116
chris schrieb: > Gibt's da keine Problem mit der Garbage Collection? Welche Implementation benutzt du, welche Garbage Collection bietet? Keine mir bekannte C++ Implementation für Mikrocontroller macht das. chris schrieb: > Gibt es ein Delete auf einem STM32 Wenn es new gibt, ja. Ob das ganze sinnvoll ist ist eine andere Frage.
Gast
#5984153
> Welche Implementation benutzt du, welche Garbage Collection bietet?
Weiß ich nicht.
Hier der nicht funktionierende Versuch auf einem ESP32:
Gast
#5984175
Und dann gehst du halt hin und machst eine schleife in der du durch den Vector iterierst, delete auf die objekte aufrufst und danch clearst du den vector.
Gast
#5984207
chris schrieb: > Hier der nicht funktionierende Versuch auf einem ESP32 Was bedeutet nicht funktionierend? chris schrieb: > Hier der nicht funktionierende Versuch auf einem ESP32: Nicht funktionieren wird wohl Compilerfehlermeldungen bedeuten. Die solltest du lesen und verstehen. Und lies die Kapitel zu Pointern und new/delete in deinem C-Buch. Oliver Oliver S. schrieb: > Und lies die Kapitel zu Pointern und new/delete in deinem C-Buch. Nein! Lies das Kapitel zu smarten pointern in einem aktuellen C++ Buch (>=C++11). In modernem C++ sollte man new/delete eigentlich nicht mehr verwenden müssen, abgesehen von einzelnen Spezialfällen. Beispiel:
Vorteile: - Es ist direkt ersichtlich, dass der vector die Lebenszeit kontrolliert. - Bei einem clear des vector werden die Instanzen sauber zerstört. Außerdem ist der Code sicherer, wenn eine Exception auftritt, weil am Ende der vector sich selbst um die Zerstörung kümmert, auch wenn du aus der Loopfunktion springst. In deinem Beispiel würde er dann beim schließen der Applikation zerstört werden. Wenn du den vector nur in loop() benötigst, dann würde ich den vector auch nur lokal in der loop Funktion anlegen. Der Stack ist dabei kein Problem, weil die Daten des vector sowieso auf dem heap liegen. Wenn dir außerdem vorher die endgültige Größe des vectors bekannt ist, dann kann du mit reserve schon mal den Speicher dafür anfordern. Das spart evtl. mehrfache Speicheranforderungen durch den vector, wenn die bisherige Anzahl von reservierten Elementen bei einem push_back überschritten wird. Dr. Sommer schrieb: > Welche Implementation benutzt du, welche Garbage Collection bietet? > Keine mir bekannte C++ Implementation für Mikrocontroller macht das. C++ kann für new/delete keine Garbage Collection verwenden, weil man sich in C++ darauf verlassen kann, das beim delete der Destruktor aufgerufen wird. Sonst würde RAII z.B. für mutexes nicht funktionieren (https://de.wikipedia.org/wiki/Ressourcenbelegung_ist_Initialisierung). Ob der Speicher dann direkt wieder dem Heap zur Verfügung gestellt wird oder dies erst mit einer Garbage Collection erfolgt ist dann wieder eine andere Sache.
Gast
#5984376
M.K. B. schrieb: > oder dies erst mit einer Garbage Collection erfolgt ist C/C++ haben keine Garbage Collection. leo leo schrieb: > C/C++ haben keine Garbage Collection. Um hier Missverständnisse zu vermeiden. Aus Sicht von new/delete gibt es keine Garbagcollection. D.h. das Objekt wird direkt zerstört und damit auch der Destruktor aufgerufen. Was ich meinte bezog sich auf die interne Implementierung des Heaps. Meines Wissens nach muss der Heap den Speicher nicht gleich bei delete wieder zu Verfügung stellen, sondern kann dies auch erst bei einer Garbagecollection tun.
Gast
#5984429
M.K. B. schrieb: > sondern kann dies auch erst bei einer > Garbagecollection tun. Was verstehst du hier nicht: C/C++ haben keine Garbage Collection. leo
Gast
#5984442
leo schrieb: > M.K. B. schrieb: >> sondern kann dies auch erst bei einer >> Garbagecollection tun. > > Was verstehst du hier nicht: C/C++ haben keine Garbage Collection. > > leo Aber C und C++ könnten einen GC in der Implementation von malloc nutzen und das ist es was M.K. B. geschrieben hat.
Gast
#5984444
mh schrieb: > Aber C und C++ könnten einen GC in der Implementation von malloc nutzen Aha. Beispiel bitte. leo
Gast
#5984450
leo schrieb: > Aha. Beispiel bitte. Ich mache es nochmal deutlicher: KÖNNTE mh schrieb: > Aber C und C++ könnten einen GC in der Implementation von malloc nutzen > und das ist es was M.K. B. geschrieben hat. Genau! leo schrieb: > Aha. Beispiel bitte. Ich kenne keine konkreten Beispiele, aber es ging bei meiner Aussage auch nur darum, dass es aus Sicht der Sprache prinzipiell erlaubt ist. Ohne mich damit jetzt im Detail auszukennen, aber ein Prozess in einem Betriebssystem könnte z.B. erstmal lokal im Prozess das free ausführen. Erst wenn eine bestimmte Zeit oder ein anderes Kriterium erfüllt ist, dann würde der Prozess diesen Speicher an das Betriebssystem zurückgeben und damit stünde dieser dann auch anderen Prozessen zur Verfügung.
Gast
#5984456
mh schrieb: > leo schrieb: >> Aha. Beispiel bitte. > > Ich mache es nochmal deutlicher: KÖNNTE Nein. [ ] Du weisst, wie ein GC funktioniert? leo leo schrieb: > Nein. > [ ] Du weisst, wie ein GC funktioniert? Um es nochmal klarzustellen. Kein GC aus Sicht von new/delete. GC bei der Speicherverwaltung durch den Heap.
Gast
#5984470
M.K. B. schrieb: > GC bei der Speicherverwaltung durch den Heap. Gibt es nicht. leo
Gast
#5984473
M.K. B. schrieb: > GC bei der Speicherverwaltung durch den Heap. Welches OS macht denn sowas? Eine MMU kann Speicherseiten ein- bzw. ausblenden. Dass ist aber kein GC.
Gast
#5984646
leo schrieb: > Aha. Beispiel bitte. https://www.hboehm.info/gc/ Der C++ Standard erlaubt definitiv ein "normales" GC in der Sprache, ähnlich wie Java. Das benutzt nur keiner. Daher der verbreitete Irrglaube, C++ würde prinzipiell kein GC unterstützen. chris schrieb: > Hier der nicht funktionierende Versuch auf einem ESP32: Das ist vorne und hinten falsch. Lies erstmal ein C++ Buch. C++ ist eine komplexe Sprache, die lernt man nicht mal eben mit ein paar Tutorials. Und überlege, ob du wirklich dynamische Speicherverwaltung brauchst. Die macht nämlich nur Sinn, wenn man Speicher zu verschiedenen Zeitpunkten unterschiedlich nutzen will, also z.B. mal 100 Test Objekte anlegen, dann wieder freigeben, dann 100 Test2 Objekte. Wenn eine solche abwechselnde Nutzung nicht gegeben ist, wird nach der Freigabe der Speicher gar nicht benutzt, wofür es kein Geld zurück gibt. Daher ist es oft besser, einfach fixe Arrays (keine Vektoren) der benötigten Größe anzulegen und nie was freizugeben.
Gast
#5984670
>Die macht nämlich nur Sinn, wenn man Speicher zu > verschiedenen Zeitpunkten unterschiedlich nutzen will, > also z.B. mal 100 Test Objekte anlegen, >dann wieder freigeben, dann 100 Test2 Objekte. Das Programm soll folgendes tun: 1. es werden N-Testobjekte angelegt ( z.B. N=100 ) 2. Die Testobjekte werden ein Zeit lang benutzt und eine Test.execute() Methode aufgerufen. 3. Der Speicher, den die Testobjekte belegen, muss wieder frei gegeben werden. 4. Goto 1. Ich vermute, dass im Framework des ESP32 keine Garbage Collection implementiert ist. In C wäre das Ganze extrem einfach zu lösen. 1. man reserviert Speicher für die Objekte und merkt sich den Speicher Anfang 2. man legt Objekte an ( Strukturen ) 3. wie oben ( 1-3) 4. Man setzt den Objektpointer zurück 5. Goto 1. Aufwand, die Objekte zu löschen: Null
Gast
#5984678
chris schrieb: > 3. Der Speicher, den die Testobjekte belegen, muss wieder frei gegeben > werden. Warum muss? Wofür wird der Speicher danach gebraucht? chris schrieb: > 4. Man setzt den Objektpointer zurück > > Aufwand, die Objekte zu löschen: Null Haha, weil du sie gar nicht löschst! Wenn du nur den Pointer auf Null setzt, ist der Speicher noch belegt, und du kannst ihn nie wieder freigeben - ein Speicherleck. Wenn du den Speicher tatsächlich freigibst, über die free() Funktion, ist der Aufwand natürlich nicht null, denn die Funktion kann ggf. nicht trivial sein. chris schrieb: > In C wäre das Ganze extrem einfach zu lösen. In C++ sogar noch einfacher dank unique_ptr. Allerdings muss man dazu schon ein bisschen wissen was man tut und nicht einfach irgendwas zusammen stoppen. chris schrieb: > Das Programm soll folgendes tun: > 1. es werden N-Testobjekte angelegt ( z.B. N=100 ) Muss dafür wirklich jedes dieser Objekte einzeln dynamisch angelegt werden? Woraus besteht so ein Objekt? Wäre es ein Problem, wenn das Objekt kopiert werden müsste? Wird Polymorphie benötigt? > 2. Die Testobjekte werden ein Zeit lang benutzt und eine Test.execute() > Methode aufgerufen. > 3. Der Speicher, den die Testobjekte belegen, muss wieder frei gegeben > werden. Muss jedes Objekt einzeln wieder freigegeben werden, oder reicht es, wenn nach den 100 Tests alle am Stück gelöscht werden? > 4. Goto 1. > > Ich vermute, dass im Framework des ESP32 keine Garbage Collection > implementiert ist. In C wäre das Ganze extrem einfach zu lösen. Was macht es in C++ denn schwierig? Man kann es da genauso machen wie in C. > 1. man reserviert Speicher für die Objekte und merkt sich den Speicher > Anfang > 2. man legt Objekte an ( Strukturen ) Wo? Wie? Oben nutzt du für jedes Objekt einzeln new. Die Entsprechung in C wäre, dass du für jede der Strukturen einzeln mit malloc() Speicher reservierst. In dem Fall müsstest du die auch alle einzeln wieder freigeben. > 3. wie oben ( 1-3) > 4. Man setzt den Objektpointer zurück > 5. Goto 1. > > Aufwand, die Objekte zu löschen: Null Verschwinden sie auf magischem Weg? chris schrieb: > In C wäre das Ganze extrem einfach zu lösen... Dr. Sommer schrieb: > Das ist vorne und hinten falsch. Lies erstmal ein C++ Buch. C++ ist eine > komplexe Sprache, die lernt man nicht mal eben mit ein paar Tutorials. Vieles, was für C++ gilt, gilt auch für C, Oliver
Gast
#5984697
Bevor man anfängt drauf los zu coden, sollte man sich erst mal überlegen: - Haben alle Objekte den gleichen Typ, oder sollen auch abgeleitete Typen möglich sein (Polymorphie)? Sollen sogar komplett unterschiedliche Typen ohne gemeinsame Basisklasse möglich sein? - Wird die Größe des Containers initial festgelegt, oder sollen Elemente einzeln hinzugefügt und einzeln gelöscht werden können? Wenn ja, wie oft? Wenn nein, steht die Größe beim Kompilieren schon fest oder erst zur Laufzeit? - Wenn die Elemente gelöscht wurden, wofür wird der Speicher dann gebraucht? Nur wieder für das erneute Befüllen des selben Containers? - Soll der Container nur von Anfang bis Ende durchgegangen werden, oder auch wahlfreier Zugriff per Index möglich sein? - Soll eine Assoziation/Mapping erfolgen, d.h. Elemente z.B. anhand eines Namens o.ä. suchen, und nicht nur nach Index? - Spielt die Reihenfolge eine Rolle? - Müssen die Elemente alle direkt im Speicher hintereinander stehen (z.B. für DMA) oder können sie verteilt sein? - Sind die Elemente simple Datenobjekte oder haben sie virtuelle Funktionen? Siehe auch: https://stackoverflow.com/q/471432 Dr. Sommer schrieb: > Der C++ Standard erlaubt definitiv ein "normales" GC in der Sprache, > ähnlich wie Java. Das benutzt nur keiner. Daher der verbreitete > Irrglaube, C++ würde prinzipiell kein GC unterstützen. Hm. Ich würde es auch so formulieren, wie M.K.B; M.K. B. schrieb: > Kein GC aus Sicht von new/delete. > GC bei der Speicherverwaltung durch den Heap. Der Sprachstandard kennt keinen GC. Der definiert allocator-/deallocator-Funktionen, die nach im Standard definierten Regeln von von new und delete aufgerufen werden. Nach Aufruf von delete ist das Objekt nicht mehr existent, und der Speicher deallokiert. Mehr definiert der Sprachstandard nicht. Der ganze Rest liegt in der Verantwortung der Implementierung. Oliver
Gast
#5984721
Rolf Magnus >Muss dafür wirklich jedes dieser Objekte einzeln dynamisch angelegt >werden? Woraus besteht so ein Objekt? Wäre es ein Problem, wenn das >Objekt kopiert werden müsste? Wird Polymorphie benötigt? Die Testobjekte sind von einem gemeinsamen Objekt abgeleitet, aber ihr Speicherverbrauch ist unterschiedlich groß. >> 2. Die Testobjekte werden ein Zeit lang benutzt und eine Test.execute() >> Methode aufgerufen. >> 3. Der Speicher, den die Testobjekte belegen, muss wieder frei gegeben >> werden. >Muss jedes Objekt einzeln wieder freigegeben werden, oder reicht es, >wenn nach den 100 Tests alle am Stück gelöscht werden? Die gesamte Testliste wird durch eine neue mit einer anderen Anzahl von Objekte ersetzt. Die alten werden nicht mehr gebraucht, die ganze Liste kann also in einem Stück gelöscht werden.
Gast
#5984728
chris schrieb: > aber ihr > Speicherverbrauch ist unterschiedlich groß. chris schrieb: > In C wäre das Ganze extrem einfach zu lösen. Jetzt bin ich gespannt, wie das "extrem einfach" in C geht. Viele unterschiedliche structs mit malloc() anlegen, Pointer darauf in ein Array, und danach alle structs und das Array mit free() freigeben? Dann stimmt aber chris schrieb: > Aufwand, die Objekte zu löschen: Null nicht. Wie schon oben angedeutet wurde, beschwert sich der C-Compiler nicht über ein fehlendes free(). Was die Programmierung natürlich sehr einfach machen kann ;) Oliver chris schrieb: > Mein Programm hat ein Array von Objekten, die mit > >
Das erzeugt kein Array, sondern ein einziges Objekt von Typen Object. Das geht auch viel einfacher mit:
C++ ist deutlich anders, als Java! Der "übliche" Weg ein Array von Objekten anzulegen, wäre dann entweder:
oder
In C++ arbeitet man viel häufiger mit Werten ohne den Umweg über Zeiger, während in Java (fast) alles erst einmal nur ein Zeiger ist, der eben auch Null sein kann.
Gast
#5984743
Um das jetzt mal etwas abzukürzen, hier ein komplettes Beispiel mit einer Basis-Klasse "Test" und 2 davon abgeleiteten, welche in einem vector abgelegt werden:
vector und unique_ptr sorgen dafür dass alles gelöscht wird. PS: Für Konstanten sollte man "constexpr" und kein "#define" nutzen. In C++ gibt es kaum einen Grund für #define, und #define kann diverse Probleme machen.
Gast
#5984893
Dr. Sommer schrieb: > leo schrieb: >> Aha. Beispiel bitte. > > https://www.hboehm.info/gc/ Was genau hat eine externe Bibliothek mit den GC-Eigenschaften der Sprache zu tun? leo
Gast
#5984901
leo schrieb: > Was genau hat eine externe Bibliothek mit den GC-Eigenschaften der > Sprache zu tun? Ist nur ein Beispiel. Der Standard vermerkt an verschiedenen Stellen etwas zur Garbage Collection, er ist praktisch aufwärtskompatibel, denn es ist nicht vollständig spezifiziert. Es wird aber in der Praxis nicht genutzt. Ist auch egal, denn der GCC für ESP kann das bestimmt nicht.
Gast
#5986251
Dr.Sommer
>Um das jetzt mal etwas abzukürzen, hier ein komplettes Beispiel
Danke für's konkret werden. Das nenne ich vorbildlich.
Hier das ganze getestet für's Arduino Framework des ESP32:
Jetzt bin ich mal gespannt, wie sich das ganze laufzeitmässig mit C schlägt. Die Test sollen nämlich im Mikrosekundenbereich und so schnell wie möglich laufen ( keine prints )
Gast
#5986269
chris schrieb: > //make_unique is an upcoming C++14 feature "Upcoming"... chris schrieb: > Jetzt bin ich mal gespannt, wie sich das ganze laufzeitmässig mit C > schlägt. Vermutlich etwas langsamer. chris schrieb: > Die Test sollen nämlich im Mikrosekundenbereich und so schnell wie > möglich laufen ( keine prints ) Du bist lustig! new/malloc und delete/free sind natürlich eher langsam. Für Echtzeit ist das natürlich vollkommen ungeeignet. Was machst du wenn kein Speicher mehr da ist? Einfach abstürzen lassen? chris schrieb: > Jetzt bin ich mal gespannt, wie sich das ganze laufzeitmässig mit C > schlägt. Dazu müsste man mal analysieren, was das Program oben macht.... Ok, gibt 11 Zahlen auf der seriellen Schnittstelle aus. Das bekommt man bestimmt auch in C "vernünftig" hin.
Gast
#5986350
Dr.Sommer >Du bist lustig! new/malloc und delete/free sind natürlich eher langsam. >Für Echtzeit ist das natürlich vollkommen ungeeignet. Es geht natürlich um die noch zu erschaffende "execute" Methode der Testklassen und nicht die Instantiierung der Objekte.
Gast
#5986359
chris schrieb: > Es geht natürlich um die noch zu erschaffende "execute" Methode der > Testklassen und nicht die Instantiierung der Objekte. Dann ist die Laufzeit des bisher diskutierten Codes also irrelevant und somit C vs. C++ auch nicht von Bedeutung? chris schrieb: > Wie kann ich alle Objekte löschen, damit das Array mit neu erzeugten > Objekten gefüllt werden kann? Warum müssen die Objekte gelöscht werden? Man kann auch Objekt-Pooling verwenden... https://de.wikipedia.org/wiki/Objektpool merciless
Gast
#5986378
Um mal konkret zu werden ;-)
FreeHeap mit Objekten:373504 test1 int:0 test1 int:1 test2 float:2.30 test2 float:3.30 average execution time per object: 0.14 us FreeHeap Objekte gelöscht:373600 test1 int:42 Falls der ESP 1Befehl/Zyklus erlaubt wären das: >> FCPU=240e6; >> timePerObject=0.14e-6; >> numberOfCpuCommandsPerObject=timePerObject*FCPU numberOfCpuCommandsPerObject = 33.600 Und ein Objekt braucht 96Byte/4 = 24Byte Speicher.
Gast
#5986397
chris schrieb: > Das Programm soll folgendes tun: > 1. es werden N-Testobjekte angelegt ( z.B. N=100 ) > 2. Die Testobjekte werden ein Zeit lang benutzt und eine Test.execute() > Methode aufgerufen. > 3. Der Speicher, den die Testobjekte belegen, muss wieder frei gegeben > werden. > 4. Goto 1. > > Ich vermute, dass im Framework des ESP32 keine Garbage Collection > implementiert ist. In C wäre das Ganze extrem einfach zu lösen. > > 1. man reserviert Speicher für die Objekte und merkt sich den Speicher > Anfang > 2. man legt Objekte an ( Strukturen ) > 3. wie oben ( 1-3) > 4. Man setzt den Objektpointer zurück > 5. Goto 1. > > Aufwand, die Objekte zu löschen: Null Ich glaube, du hast C/C++ so gar nicht verstanden. Es gibt in C malloc und free, man braucht nur 1 Aufruf um ein ganzes Array im noch freien heap Speicher zu reservieren, und wieder freizugeben. New und delete von C++ tun dasselbe, so lange in der Klassenstruktur nur einfache Variablen enthalten sind, keine weiteren Objekte (also structs mit ihrer eigenem Constructor und Destructor), und können auch ein ganzes Array auf einen Schlag behandeln. Im einfachsten Fall macht malloc/new:
MaWin schrieb: > Ich glaube, du hast C/C++ so gar nicht verstanden. > > Es gibt in C malloc und free, man braucht nur 1 Aufruf um ein ganzes > Array im noch freien heap Speicher zu reservieren, und wieder > freizugeben. Und wie allokierst du ein Array aus lauter unterschiedlich großen Elementen? chris schrieb: > Die Testobjekte sind von einem gemeinsamen Objekt abgeleitet, aber ihr > Speicherverbrauch ist unterschiedlich groß. chris schrieb: > Um mal konkret zu werden ;-) Konkret wird es erst, wenn Du weist, welches Problem Du eigentlich lösen möchtest. > average execution time per object: 0.14 us Absolute irrelevant, wenn in diesen 140ns kein Problem gelöst wurde. Dafür ist das noch viel zu viel Zeit. > Und ein Objekt braucht 96Byte/4 = 24Byte Speicher. Wer mist, mist Mist. Sowohl `sizeof( Test1 )`, also auch `sizeof( Test2 )` werden wohl 8 sein. Ist aber auch egal, weil Du nicht weißt, was `ESP.getFreeHeap()` überhaupt für einen Wert zurück gibt. Wenn das wirklich wichtig wäre, dann verzichtest Du am besten auf die Verwendung des heaps. Rolf M. schrieb: > Und wie allokierst du ein Array aus lauter unterschiedlich großen > Elementen? Der OP hatte "unterschiedlich groß" eigentlich nie erwähnt. Aber: Man könnte die dynamischen Typen alle hinter einander legen und dazu noch einen Array mit Zeigern auf den statischen Typen, um die Anfangsadressen zu bekommen.
Gast
#5986439
Rolf M. schrieb: > Und wie allokierst du ein Array aus lauter unterschiedlich großen > Elementen Grundlagen der Programmierung: Ein Array besteht aus gleichartigen Elementen. Bei unterschiedlich grossen kann man nicht berechnen, dass das dritte Element bei 2+sizeof(element) steht. Man braucht Pointer, geht aber auch, gern gemacht um strings in Worte zu zerlegen oder so:
Da reicht dann 1 free um alle loszuwerden. Torsten R. schrieb: > Der OP hatte "unterschiedlich groß" eigentlich nie erwähnt. Hä? Ich hab doch die Stelle, wo er das erwähnt hat, zitiert. Rolf M. schrieb: > Torsten R. schrieb: >> Der OP hatte "unterschiedlich groß" eigentlich nie erwähnt. > > Hä? Ich hab doch die Stelle, wo er das erwähnt hat, zitiert. Sorry, habe ich übersehen!
Gast
#5988826
Hier ein Versuch mit einer Objektliste fester Länge. Meine Vermutung war, dass die "execute"-Schleife etwas schneller ist und das die verkehrte Reihenfolge beim Löschen der Objekte zu Problemen führt. Aber scheinbar bleibt alles wie beim vorigen Beispiel. Die Ausführungszeit ist gleich und mit dem "delete" der Objekte scheint es wohl auch kein Problem zu geben.
Gast
#5989429
Super Sache: Man kann den Compiler-Explorer verwenden, um den Assemblercode für verschiedene MCUs zu analysieren: https://godbolt.org/
Gast
#5989430
Tschuldigung ... die Dateiendung für das Bild fehlt.
Gast
#5989450
chris schrieb: > Man kann den Compiler-Explorer verwenden, um den Assemblercode für > verschiedene MCUs zu analysieren: Mit objdump geht das auch lokal. Schalte mal die Optimierungen ein!
Gast
#5991756
Hier im Netz gibt es einen schönen Artikel zu malloc und Heap-Fragmentierung: https://www.mikrocontroller.net/articles/Heap-Fragmentierung Wird "malloc" bei C++ noch verwendet? Ich suche nach einer Möglichkeit, in einem Objekt beim Instantiieren eine variable Speichergröße anzulegen und später das Objekt mitsamt Speicher wieder zu löschen.
Gast
#5991758
chris schrieb: > Wird "malloc" bei C++ noch verwendet? Ja, "new" ruft das auf. chris schrieb: > Ich suche nach einer Möglichkeit, in einem Objekt beim Instantiieren > eine variable Speichergröße anzulegen und später das Objekt mitsamt > Speicher wieder zu löschen. Also ein vector, genau wie gezeigt... chris schrieb: > Hier im Netz gibt es einen schönen Artikel zu malloc und > Heap-Fragmentierung: Das ist halt das Problem bei dynamischer Speicherverwaltung. Zum Glück braucht man die bei Embedded Systems auch fast nie... chris schrieb: > Wird "malloc" bei C++ noch verwendet? Entweder verwendet "new", "malloc" direkt, oder eben etwas, das sehr ähnlich funktioniert. > Ich suche nach einer Möglichkeit, in einem Objekt beim Instantiieren > eine variable Speichergröße anzulegen und später das Objekt mitsamt > Speicher wieder zu löschen. Da Du das auf einer Hardware mit begrenztem Speicher laufen lassen möchtest, wäre der "übliche" Weg, Dir eine Maximalgröße zu überlegen und den Speicher genau für dieses Maximalgröße anzulegen.
Gast
#5992029
Dr. Sommer
>Also ein vector, genau wie gezeigt...
Ist der geeignet, um in den verschiedenen Objekten ein "uin16_t" Array
mit 10-4000 Werten anzulegen ( je nach geforderter Größe bei der
Instantiierung )? Wird in einem Vector nicht eine "linked list"
angelegt, die 3x soviel Speicher braucht?
Gast
#5992045
chris schrieb: > Ist der geeignet, um in den verschiedenen Objekten ein "uin16_t" Array > mit 10-4000 Werten anzulegen Ja natürlich. chris schrieb: > Wird in einem Vector nicht eine "linked list" angelegt, die 3x soviel > Speicher braucht? Nein, das macht std::list. vector legt ein Array aus zusammenhängendem Speicher an.
Gast
#5992048
chris schrieb: > Wird in einem Vector nicht eine "linked list" > angelegt, die 3x soviel Speicher braucht? Wie kommt man auf so eine Idee?
Gast
#5992176
Autor: mh (Gast) >Wie kommt man auf so eine Idee? Von hier: https://de.cppreference.com/w/cpp/container/vector "Der Speicherplatz des Vektors wird automatisch angepasst, er wird je nach Bedarf erweitert und verkleinert. Vektoren belegen in der Regel mehr Platz als statische Arrays, weil mehr Speicher zugewiesen wird um zukünftiges Wachstum zu behandeln." Zugegeben, das mit der "linked list" war eine Vermutung. Aber zumindest hat "vector" einen Overhead. Die Frage ist, wie groß?
Gast
#5992228
chris schrieb: > Aber zumindest hat "vector" einen Overhead. Die Frage ist, wie groß? Ca 16 Bytes (einmalig). Siehe auch die Funktion std::vector::reserve... chris schrieb: > "Der Speicherplatz des Vektors wird automatisch angepasst, er wird je > nach Bedarf erweitert und verkleinert. Vektoren belegen in der Regel > mehr Platz als statische Arrays, weil mehr Speicher zugewiesen wird um > zukünftiges Wachstum zu behandeln." > > Zugegeben, das mit der "linked list" war eine Vermutung. Aber zumindest > hat "vector" einen Overhead. Die Frage ist, wie groß? Das kommt drauf an. Wenn der Platz, den ein vector bietet, aufgebraucht ist, muss er reallokieren, d.h. einen neuen, größeren Speicherplatz belegen, alle bereits enthaltenen Daten rüberkopieren und dann den ursprünglichen Speicherbereich freigeben. Da man vermeiden möchte, dass das bei jedem einzelnen Hinzufügen eines Elements passiert, wird bei jeder Reallokation der Bereich üblicherweise nicht nur um ein einzelnes Element, sondern um einen bestimmten Faktor gegenüber dem vorherigen vergrößert, so dass noch Platz für weitere Elemente ist, bevor wieder neu reallokiert werden muss. Wie groß dieser Faktor ist, hängt von der Implementation ab. Manche verdoppeln z.B. immer. Während der Reallokation braucht der vector kurzzeitig dann also den dreifachen Platz (alter Speicherbereich + neuer, doppelt so großer Bereich). Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|