Dynamisches String Array (Vektor)
-
Gehard schrieb:
Judden Dach.
Grüß Gott!
Ich möchte mich kurz fassen. Ich habe ein Programm das eine Eingabe von mehreren Strings abspeichern muss. Diese Strings können in der Anzahl zwischen 1 und 500 liegen. Ich habe schon bei meiner Suche einiges über Vektoren gehört jedoch verstehe ich die Syntax und die Verwendung noch nicht so ganz. Kann mir hier einer mal einen kleinen Start geben?
Vielleicht ein Beispiel + kurze Erläuterung bitte.Gruß
Nimm ein Buch und lies dir das Kapitel über Pointer durch.
-
314159265358979 schrieb:
Der vector holt sich am Anfang einen Speicherbereich, sagen wir für 8 Elemente. Wenn du ein 9tes einfügst, holt er sich einen neuen Speicherbereich, der im Normalfall 1.5 bis 2 mal so groß ist wie der alte und kopiert alle Elemente rüber. Unter C++0x werden Elemente gemovt, wenn move-Semantik vom gespeicherten Typen unterstützt wird.
Ist das wirklich so?
Dachte, daß der wesentliche Vorteil eines Vektors darin besteht, mit "new" dynamisch Speicher vom sogenannten "Heap" anzufordern, so daß die alten Elemente nicht nochmal kopiert werden müssen.
-
Deshalb kann man dem vector mit reserve() sagen, wie viele Elemente man erwartet - um unnötiges Kopieren zu vermeiden.
-
314159265358979 schrieb:
Unter C++0x werden Elemente gemovt, wenn move-Semantik vom gespeicherten Typen unterstützt wird.
Das ist aber nicht immer sicher. Was ist, wenn der move-Konstruktor eine exception schmeist? Das funktioniert nur, wenn es für den move-Konstruktor eine starke exception garantie gibt. (anbei: Ist für c++0x sowas wie is_nothrow_move_constructible<T> geplant bzw. schon umgesetzt? Was in dem Zusammenhang fast noch interessanter wäre, ist sowas wie is_mem_movable, das man selber spezialisieren kann, um zu zeigen, dass das Objekt per memcpy gemoved werden darf. Ein string, der als einziger Besitzer eines char arrays irgendwo im Speicher implementiert ist, wäre zum Beispiel ein Kandidat für sowas.)
-
redrew99 schrieb:
314159265358979 schrieb:
Der vector holt sich am Anfang einen Speicherbereich, sagen wir für 8 Elemente. Wenn du ein 9tes einfügst, holt er sich einen neuen Speicherbereich, der im Normalfall 1.5 bis 2 mal so groß ist wie der alte und kopiert alle Elemente rüber. Unter C++0x werden Elemente gemovt, wenn move-Semantik vom gespeicherten Typen unterstützt wird.
Ist das wirklich so?
Dachte, daß der wesentliche Vorteil eines Vektors darin besteht, mit "new" dynamisch Speicher vom sogenannten "Heap" anzufordern, so daß die alten Elemente nicht nochmal kopiert werden müssen.Da dachtest du falsch.
std::vector muss definitiv umkopieren (bzw. "ummoven").
-
GorbGorb schrieb:
314159265358979 schrieb:
Unter C++0x werden Elemente gemovt, wenn move-Semantik vom gespeicherten Typen unterstützt wird.
Das ist aber nicht immer sicher. Was ist, wenn der move-Konstruktor eine exception schmeist?
Dann wird er nicht verwendet.
Dazu gibt esstd::is_nothrow_move_constructible<T>undstd::move_if_noexcept.
-
Zu Move-Semantik und Exceptionsicherheit gabs übrigens gerade erst eine kurze Diskussion.
-
redrew99 schrieb:
Soweit ich das mitbekommen habe, ist ein Vektor nichts anderes als "stinknormales" Array, was durch die Einbettung in eine Klasse mehr Funktionalität bietet.
Da liegst du zumindest teilweise falsch, die Entsprechung eines C Arrays entspricht als Klasse im wesentlichen std::tr1::array, der Vektor kann mehr (wie z.B. das umkopieren bei Bedarf, was ein normales Array nicht kann...).
-
hustbaer schrieb:
Dann wird er nicht verwendet.
Dazu gibt esstd::is_nothrow_move_constructible<T>undstd::move_if_noexcept.Also ist das im neuen Standard mit dabei? Mein gcc kennts nämlich nocht nicht...
asc schrieb:
redrew99 schrieb:
Soweit ich das mitbekommen habe, ist ein Vektor nichts anderes als "stinknormales" Array, was durch die Einbettung in eine Klasse mehr Funktionalität bietet.
Da liegst du zumindest teilweise falsch, die Entsprechung eines C Arrays entspricht als Klasse im wesentlichen std::tr1::array, der Vektor kann mehr (wie z.B. das umkopieren bei Bedarf, was ein normales Array nicht kann...).
Ich denke er meinte eher, dass der vector intern ein normales array verwendet.
-
GorbGorb schrieb:
hustbaer schrieb:
Dann wird er nicht verwendet.
Dazu gibt esstd::is_nothrow_move_constructible<T>undstd::move_if_noexcept.Also ist das im neuen Standard mit dabei?
Ja. Falls das entsprechende Objekt kopierbar ist und der move-ctor eine Ausnahme schmeißen könnte, liefert move_if_noexcept eine "Lvalue-Referenz auf const".
Wenn T nicht kopierbar ist und einen potentiell schmeißenden Move-Ctor hat, dann hat der vector keine andere Wahl, darauf zu hoffen, dass beim Vergrößern alles gut geht. Wenn in dem Fall wirklich eine Ausnahme fliegt, ist der Zustand des Vektors unspezifiziert.
Also, Klassen, die nur "movable" sind, sollten dann wirklich keine Ausnahme im move-ctor schmeißen.
-
GorbGorb schrieb:
Ich denke er meinte eher, dass der vector intern ein normales array verwendet.
Ja, genau.