Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// Neuer std::vector soll gefüllt werden. std::vector<MyClass*> Vec; Vec.push_back(new MyClass()); // OK Vec.push_back(new MyClass()); // Memory Leak, falls MyClass-Konstruktor Vec.push_back(new MyClass()); // Exception wirft oder falls new fehlschlägt // Temporäre Kopie anlegen, wir brauchen die jetzt. Neues Element hinzufügen. std::vector<MyClass*> Vec2 = Vec; // OK Vec2.push_back(new MyClass()); // OK // Nachträglich Element in alten Vector einfügen, das nicht in Vec2 kopiert werden soll. Vec.push_back(new MyClass()); // OK // Schlussendlich (nach irgendwelchem Code) soll der alte Vector wieder 3 Elemente enthalten. Vec2.resize(3); // garantiertes Memory Leak // Vec soll sortiert werden std::sort(Vec.begin(), Vec.end()); // OK // Wir möchten alle Elemente aus Vec2 löschen. for (int i = 0; i < Vec2.size(); ++i) delete Vec[i]; // OK, alle Elemente in Vec2 korrekt freigegeben. Vec2.clear(); // OK, vector mit ungültigen Zeigern geleert. // Wir möchten Vec1 korrekt freigeben. // Wir merken, dass wir nicht jedes Element deleten dürfen, da ein Teil des Speichers bereits // in Vec2 freigegeben wurde. Wir sehen auch sogleich, dass keine Möglichkeit besteht, heraus- // zufinden, welche Zeiger bereits freigegeben wurden. Nett, wir haben die Wahl zwischen // doppeltem Delete und Memory Leaks. |
Zitat von »"Nexus"«
Laguna, das versprochene Beispiel:
C-/C++-Quelltext
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // Neuer std::vector soll gefüllt werden. std::vector<MyClass*> Vec; Vec.push_back(new MyClass()); // OK Vec.push_back(new MyClass()); // Memory Leak, falls MyClass-Konstruktor Vec.push_back(new MyClass()); // Exception wirft oder falls new fehlschlägt // Temporäre Kopie anlegen, wir brauchen die jetzt. Neues Element hinzufügen. std::vector<MyClass*> Vec2 = Vec; // OK Vec2.push_back(new MyClass()); // OK // Nachträglich Element in alten Vector einfügen, das nicht in Vec2 kopiert werden soll. Vec.push_back(new MyClass()); // OK // Schlussendlich (nach irgendwelchem Code) soll der alte Vector wieder 3 Elemente enthalten. Vec2.resize(3); // garantiertes Memory Leak // Vec soll sortiert werden std::sort(Vec.begin(), Vec.end()); // OK // Wir möchten alle Elemente aus Vec2 löschen. for (int i = 0; i < Vec2.size(); ++i) delete Vec[i]; // OK, alle Elemente in Vec2 korrekt freigegeben. Vec2.clear(); // OK, vector mit ungültigen Zeigern geleert. // Wir möchten Vec1 korrekt freigeben. // Wir merken, dass wir nicht jedes Element deleten dürfen, da ein Teil des Speichers bereits // in Vec2 freigegeben wurde. Wir sehen auch sogleich, dass keine Möglichkeit besteht, heraus- // zufinden, welche Zeiger bereits freigegeben wurden. Nett, wir haben die Wahl zwischen // doppeltem Delete und Memory Leaks.
Zitat
shared_ptr nehmen. Also: std::vector< boost::shared_ptr < MyClass > >
Es ist noch einiges Basiswissen, und trotzdem wissen es viele Leute nicht. Es ging übrigens nicht nur ums Kopieren. Und dein Vergleich mit C trifft es gut: Man verwendet unsichere, fehleranfällige und aufwändige Techniken in C++, obwohl man das Problem mit weniger Code besser lösen könnte. Nicht ohne Grund verwende ich keine rohen C-Arrays mehr, sofern ich nicht an irgendwelche Schnittstellen gebunden bin.Zitat von »"dv"«
std::vector<MyClass*> zu kopieren, das macht man nicht. Das ist nichts gefinkeltes o.ä., das ist Basiswissen - wenn du in C einen Array von Pointern herumkopierst, wirst du ähnliche Probleme kriegen.
Werbeanzeige