vector<string> initialisieren.. -> string==/!=string langsamer als strcmp()??
-
Hallo,
beschäftige mich nun erstmals mit std::vector und stoße gleich auf ein kleines Problem. Offensichtlich funtioniert soetwas nicht:
(std:: lasse ich in den Beispielen zur Übersicht weg)
(Auch ist die Liste der string Elemente stark verkürzt, es sind 27 Elemente, hier nur 5)Ich wollte das std::string Array:
string sprache[5] = { "Deu", "Eng", "Rus", "Pol", "Lit" };Als Vector anlegen, ohne weiterhin das string Array zu verwenden.
(Also nicht, das string Array und den vector anlegen und das string Array dann hineinkopieren)vector <string> sprache(5) = { "Deu", "Eng", "Rus", "Pol", "Lit" };/\
||
Also, so funktioniert es schonmal nicht. LOL (Wäre auch zu einfach gewesen!!)Gut, nach einigem Durchforsten in der Klassenbeschreibung kam ich dann auf diese Lösung:
vector <string> sprache("Deu","Eng","Rus","Pol","Lit"};ABER --> Das funktioniert so auch nicht, nur für 2 Elemente, ab 3 Elementen passt wohl der Construktor nicht mehr.
Soweit habe ich es ja nun verstanden, daß es nicht geht, aber gibt es eine Möglichkeit, daß es geht?
Meine bisherige Lösung:
vector<string> sprache; sprache.push_back("Deu"); sprache.push_back("Eng"); sprache.push_back("Rus"); sprache.push_back("Pol"); sprache.push_back("Lit");funktioniert bestens, aber ist ein wenig umständlich, da ich sehr große string Arrays habe. mit 27, 41 und 138 string Elementen.
Schön wäre eine Initialisierung im Stil von:
vector<string> sprache ..irgendwie die string Elemente reinpacken..Also direkt mit den string Elementen initialisieren.
Mir würde auch eine Antwort der Art:
"Geht nicht." helfen, dann muß ich nicht weiter suchen und kann wieder ruhig schlafen.
Gruß,
DC
-
Hier hast Du die zur Verfügung stehenden Konstruktoren:
http://cplusplus.com/reference/stl/vector/vector/
Was Du möchtest, geht nicht. Du könntest den Vektor mit einer Anzahl gleicher Werte initialisieren (Die zweite Version), oder mit einem bereits vorhandenen Objekt, auf das mit Iteratoren zugegriffen werden kann (Version Drei) oder mit einem bereits vorhandenen Vektor (die letzte Version).
Mehr ist nicht.
-
Alles klar, das hilft mir weiter, dann nehme ich die push_back Version um den Vector zu füllen.
Danke für die flotte Antwort..
Gruß,
DC
-
Doch, doch, das geht.
Die Konstruktorvariante
template <class InputIterator> vector (InputIterator first, InputIterator last, const Allocator& = Allocator())sollte funktionieren, folgendermaßen:std::string strarr[] = {"str1", "str2", "str3", "str4"}; std::vector<std::string> strvec(strarr, strarr + sizeof(strarr) / sizeof(std::string));Zeiger sind auch Iteratoren, wenn es nach der STL geht.
-
Don Carsto schrieb:
Ich wollte das std::string Array:
string sprache[5] = { "Deu", "Eng", "Rus", "Pol", "Lit" };Als Vector anlegen, ohne weiterhin das string Array zu verwenden.
(Also nicht, das string Array und den vector anlegen und das string Array dann hineinkopieren)
-
Für sowas kann man schön Boost.Assign nehmen.
#include <boost/assign/std/vector.hpp> // ... vector<string> v; v += "Deu", "Pol", "Lit", "...";Natürlich hast du dann eine zusätzliche Abhängigkeit, die ist in dem Fall aber marginal.
-
Ich dachte, er meinte damit soetwas wie push_back. Noch ein bisschen früh für mich...
Naja, dann eben Zustimmung für Belli: Geht nicht.
-
Wow, die Lösung mit boost gefällt mir.
Vielen Dank!!
Gruß,
DC
-
Wenn du einen aktuellen Compiler benutzt, der den neuen ( noch nicht verabschiedeten ) Standard unterstützt, kannst du den Vector genau so wie das Array initialisieren. gcc 4.5 oder VisualStudio 2010 unterstützen dies bereits.
-
Hmm, meinst du so?
vector <string> sprache(5) = { "Deu", "Eng", "Rus", "Pol", "Lit" };(Mit runden Klammern, oder mit Eckigen?)
Habe GCC 4.5, aber mit runden Klammern hat es nicht geklappt.
Gruß,
DC
-
Hmmm, so geht es...
vector<string> sprache= { "Deu", "Eng", "Ita", "Fra", "Gri" };
-
gcc 4.5 oder VisualStudio 2010 unterstützen dies bereits.
Also VS2010 unterstützt das leider noch nicht, zumindest bekomme ich den Fehler
error C2552: 'sprache' : non-aggregates cannot be initialized with initializer list
-
Allerdings hat er wohl nun Probleme, den Speicher wieder freizugeben jedenfalls schmeisst er mit nun beim Verlassen der Funktion einen Ausnahmefehler.
Ich probiere es nun erst einmal mit der boost Lösung.
-
Tja, mit der boost Lösung das gleiche Problem.
Nach Verlassen der Funktion ein Ausnahmefehler.
Nur meldet mir der Compiler diesmal, daß er einen nicht-virtuellen Destruktor hat.Gehe ich recht in der Annahme, daß der vector am Ende nicht freigegeben werden kann und deswegen diesen Ausnahmefehler erzeugt?
-
Don Carsto schrieb:
Gehe ich recht in der Annahme, daß der vector am Ende nicht freigegeben werden kann und deswegen diesen Ausnahmefehler erzeugt?
Dies wäre äußerst ungewöhnlich. Zeig mal mehr Code. Das mit dem fehlenden virtuellen Destruktor klingt schon einmal verdächtig. Erbst du etwa von einem STL-Container?
-
Don Carsto schrieb:
Also, so funktioniert es schonmal nicht. LOL (Wäre auch zu einfach gewesen!!)
Mit Raten kommst Du in C++ nicht weit. Die Sprache bietet da so einige Irregularitäten. Das kann man sich nicht alles selbst zusammen reimen.
-
Don Carsto schrieb:
Tja, mit der boost Lösung das gleiche Problem.
Nach Verlassen der Funktion ein Ausnahmefehler.Wahrscheinlich rufst Du irgendwo undefiniertes Verhalten hervor.
Don Carsto schrieb:
Nur meldet mir der Compiler diesmal, daß er einen nicht-virtuellen Destruktor hat.
Wer hat einen nicht-virtuellen Destruktur und warum sollte das hier eine Rolle spielen?
Don Carsto schrieb:
Gehe ich recht in der Annahme, daß der vector am Ende nicht freigegeben werden kann und deswegen diesen Ausnahmefehler erzeugt?
Falsch geraten.
Versuche das Programm zu verkürzen und vereinfachen und damit den Fehler zu isolieren. Oft findet man so schon den Übeltäter. Wenn Du uns ein kurzes, komplettes Programm zeigen kannst, was sich Deiner Meinung nach ähnlich komisch verhält, dann kann man mehr dazu sagen. Betonung liegt auf "kurz" und "komplett".
-
SeppJ schrieb:
Dies wäre äußerst ungewöhnlich. Zeig mal mehr Code. Das mit dem fehlenden virtuellen Destruktor klingt schon einmal verdächtig. Erbst du etwa von einem STL-Container?
Ich habe nun mal das Ganze in eine einfache Consolen Anwendung gepackt. Die Warnungen mit dem non-virtuell-destruktor kommen trotzdem, aber es läuft ohne Ausnahme durch. (Die Warnungen kommen schon,wenn ich nur die boost-include einbinde) Liegt wohl eher an der hohen Warnstufe des Compilers.
Nun habe ich mal den "fehlerhaften" Code komplett gekürzt und schwupps läuft es durch.
Da scheint irgendein anderes böses Objekt die Ausnahme zu erzeugen.Leider ist der Coee so lang und komplex, daß ein posten nicht viel Sinn macht.
Da ich nun weiß, daß es nicht am vector selbst liegt, sondern eher an dem chaotischen Drumherum, werde ich das mal entwirren (Schritt für Schritt ausblenden) und die fehlerhafte Stelle suchen.
Sinn des Ganzen war sowieso zunächst den Code komplett zu Überarbeiten, um unsichere Stellen auszumerzen.
zu krümelkacker: (Post erst während der Erstellung gelesen)
Ja, leider kann ich keinen vereinfachten Code posten, der sich ähnlich verhält.
Und das mit dem Isolieren habe ich gerade in Angriff genommen. Mal sehen.Jedenfalls funktioniert die boost-Lösung und auch die GCC 4.5 mit dem noch nicht freigegebenen C++ Standard auch. Der Übeltäter ist irgendwo anders im Code.

Vielen Dank nochmal für die Unterstützung. Und die Lösung des Problems.
So.. nun gehts ans Fehlersuchen...

Gruß,
DC
-
So, habe die letzten Stunden damit verbracht den Fehler zu suchen.
Es lag an einem zu kleinen char filestring[40];
Dieses wurde wohl etwas zu weit (um 3 Zeichen) überschrieben.
Dadurch wurde die restliche Speicherverwaltung überaus brüchig.
Hatte sich bisher noch nie bemerkbar gemacht, doch seit ich nun auf std::strings und std::vector umgestellt habe, wurden Ausnahmen geschmissen.Eine tickende Zeitbombe....
-
Ich hoffe mal schwer, du hast nun das
char[]-Array durchstd::stringersetzt und nicht nur um 3 Zeichen vergrössert...
Wechsle bei der Gelegenheit am besten alle rohen C-Arrays aus (gegen
std::tr1::array,boost::array, oderstd::array- alles das Gleiche) und ersetze alle Zeiger auf dynamische Arrays durchstd::vector.
-
Ja, bin dabei, den kompletten Code zu überarbeiten.
Das war ja auch Sinn der Übung, daß ich die char Arrays durch std:string ersetzen wollte, a) um zu gucken, ob es dann eine Performance-Erhöhung gibt und b) weil ich std::string sicherer von der Speicherverwaltung halte.
Nebenher wollte ich dann auch gleich alle mehrdimensionalen char Arrays durch vector<string> ersetzen.Habe nun erstmal eine einigermassen lauffähige Version erschaffen, die sich nun genauso verhält wie die Alte, außer, daß es nun 3x-langsamer geworden ist.
Habe aber auch noch nicht den kompletten Code umgebastelt.
Sind noch einge Krücken drinne.