Verständnissfrage std::vector
-
Kurzer Beispielcode:
class Entry { ... public: std::string getData() {...} ...}; class Database { std::vector<Entry> m_EntryList; ... ... Entry* CreateNewEntry() {m_EntryList.push_back(Entry); return &m_EntryList.back();}Ich möchte mehrere Entry-Klassen in Database speichern, wenn ich ein Entry erstelle gibt er mir einen Pointer auf den neusten Entry zurück damit ich die Klasse manuell mit Daten auffüllen kann.
PROBLEM:
//... Entry* Entry1 = MyDatabase->CreateNewEntry(); Entry* Entry2 = MyDatabase->CreateNewEntry(); Entry1->getData(); //FEHLER DA POINTER NICHT MEHR GÜLTIG! //...Liege ich damit richtig dass beim erstellen von Entry2 der erste Eintrag umkopiert wird und damit einen neuen Speicherbereich erhält? Gibt es eine Möglichkeit dieses umkopieren zu verhindern oder muss ich das völlig anders lösen?

-
Rookie86 schrieb:
Liege ich damit richtig dass beim erstellen von Entry2 der erste Eintrag umkopiert wird und damit einen neuen Speicherbereich erhält? Gibt es eine Möglichkeit dieses umkopieren zu verhindern oder muss ich das völlig anders lösen?

- Ja, es wird das interne Array umkopiert, wenn der Vector wachsen muss.
- Ja, verwende einen Vector mit Pointern. Wenn deine createEntry-Methode eh nen pointer zurück liefert, kannst du die auch gleich im Vector speichern. Der Pointer bleibt dann auch gültig.
class Database { std::vector<Entry*> m_EntryList; ... ... Entry* CreateNewEntry() { Entry* e = new Entry; m_EntryList.push_back(e); return e; }
-
Vielen dank für die schnelle Antwort.

-
Ein Umkopieren kannst du auch verhindern, in dem du mit reserve schon einmal bekannt gibst, wie viele Platz du gleich brauchen wirst.
Macht natürlich nur Sinn, wenn du das schon vorher weißt. Bei dir ist das wahrscheinlich jetzt nicht der Fall, sollte man aber im Hinterkopf behalten.
-
Wenn Referenzen, Zeiger und Iteratoren auf die Elemente gültig bleiben müssen, ist
std::listeine sehr gute Wahl für einen sequentiellen Container. Mitstd::vector::reserve()hat man das gleiche Problem wie mit statischen Arrays: Man kann die Grösse nicht dynamisch vorhersagen, und zu waghalsige Schätzungen können viel Speicher verschwenden.
-
Athar schrieb:
Ein Umkopieren kannst du auch verhindern, in dem du mit reserve schon einmal bekannt gibst, wie viele Platz du gleich brauchen wirst.
Macht natürlich nur Sinn, wenn du das schon vorher weißt. Bei dir ist das wahrscheinlich jetzt nicht der Fall, sollte man aber im Hinterkopf behalten.Dann lieber std::array, weil man dann nicht ausversehen nochmal die Größe ändern kann.
-
rüdiger schrieb:
Dann lieber std::array, weil man dann nicht ausversehen nochmal die Größe ändern kann.
Da muss die Grösse aber schon zur Kompilierzeit bekannt sein. Ausserdem eignet sich der Stack nicht für sehr grosse Speicherbereiche (da der Container seine Objekte auf dem Stack anfordert, wenn er nicht selbst im Freestore/Heap bzw. im statischen Bereich liegt).