Liste aus char* einen Vector aus strings zuweisen
-
Wenn ich es richtig verstehe:
std::list<char*> lst; // fill lst std::vector<char*> vec; vec.resize(lst.size()); std::copy(lst.begin(), lst.end(), vec.begin());
-
Ich denk mal es war genau andersrum gemeint Airdamm.
Von vec nach Liste ginge es in etwa so:
std::list<char*> lst; std::vector<std::string> vec; //vector fuellen for (std::vector<std::string>::iterator it = vec.begin(); it != vec.end; ++it) { std::size_t clength = it->length() + 1; //der c-string hat noch das abschliessende '\0' char* str = new char[clength]; //neues char-array const char* pc = it->c_str(); std::copy(pc, pc+(clength), str); //oder auch std::strcopy lst.push_back(str); } //have fun with the list! while (! lst.empty()) { delete[] lst.front(); lst.pop_front(); }
-
@Airdamm:
Egal ob deine Lösung nun zum OP passt oder nicht - ich bin gerade am überlegen ob sich das list.size() lohnt, da hat ja immerhin auch lineare Komplexität. Mir gefallen irgendwie beide Varianten nicht.
Ich glaub ich würde das einfach dem Range-Konstruktor von vector überlassen und auf eine intelligente Implementierung hoffen.
-
die implementierung des range-ctors wird sicherlich kein size erfragen, da selbst difference() für die iteratoren nicht definiert sein muss. Selbst Airdamms variante wäre mit einem back_inserter(vec.end()) um den size() Aufruf herumgekommen

-
Naja mit dem back_inserter hast du dann halt wieder die wiederkehrenden Vergrößerungen.
Es sei denn, du benutzt v.resize( l.size()). Okay, diese Variante erspart sich das Rumkopieren. Aber bei meinetwegen 1000 Elementen spielt das eh keine Rolle.
War mal nur laut gedacht am Abend. 
-
7H3 N4C3R schrieb:
Naja mit dem back_inserter hast du dann halt wieder die wiederkehrenden Vergrößerungen.
Es sei denn, du benutzt v.resize( l.size())Ich hoff du meinst reserve()
denn mti resize() UND back_inserter hast du dann N default-konstruierte Elemente und danach nochmal N kopierte 
-
Danke für die Antworten.
Besonders dir pumuckl, so hatte ich die Aufgabe auch verstanden!
Ohne Speicher allokieren zu müssen gehts auf keinen Fall, oder?
-
Nachtrag:
Also in diesem Falle auch nur als Pointer auf das erste Zeichen vom jeweiligen Vector-String, der ja auf dem Stack liegt.
-
ohne dynamisches allokieren gehts nicht, nein.
beim std::string macht die klasse das für dich, was bei einem std::string auf dem stack liegt sind nur die rahmendaten, hauptsächlich ein Pointer, evtl ein size_t der die Länge speichert usw.
In diesem Fall liegt aber nichtmal das auf dem Stack, da der vector seine gespeicherten Daten auch dynamisch verwaltet (wie so ziemlich alle Container, also auch die list).std::string::c_str() liefert dir einen const char* auf das erste Zeiche vom String. Allerdings kannst du den nicht einfach in die Liste stecken, da dir erstens das const in die Quere kommt (const ist es weil du über den Pointer nicht in den String-Eingeweiden Rumwerkeln sollst) und zweitens dem string ausdrücklich erlaubt ist, seinen Inhalt zu einem späteren Zeitpunkt an einen anderen Ort zu kopieren und den Speicher wieder freizugeben. In so einem Fall würden die pointer in der List dann irgendwo in den Speicher zeigen, wo schon längst kein String mehr anzutreffen ist.
-
pumuckl schrieb:
Ich hoff du meinst reserve()
denn mti resize() UND back_inserter hast du dann N default-konstruierte Elemente und danach nochmal N kopierte 
Man achte bitte auf die Uhrzeit *reusper*

-
Super, danke für die ausführliche Erklärung!
-
vielleicht gehts auch ohne allokieren, da die zeiger solange gültig sind solange man die strings nicht anfasst.
wenn du also den vector nicht benutzt kannst du die zeiger in der liste speiciehrn
-
helferlein schrieb:
vielleicht gehts auch ohne allokieren, da die zeiger solange gültig sind solange man die strings nicht anfasst.
wenn du also den vector nicht benutzt kannst du die zeiger in der liste speiciehrnDie Restritkionen wären aber immens. Viele Zugriffe auf den vector können dafür sorgen, dass der neuen Speicher allozieren muss, dadurch die Strings umkopiert, wodurch wiederum die Zeiger in der Liste ungültig werden (können). Wenn man den vector umkopiert kommts natürlich genauso. Da vermutlich irgendjemand anderes den Code später modifiziert muss dem mit großen roten Warntafeln und Starkstromzäunen klargemacht werden, dass er auf keinen Fall den vector berühren soll... Dann doch lieber dynamisch Speicher anfordern oder noch besser garnicht erst mit blanken char-pointern hantieren. Gut dass das nur als Übung gedacht war
