Abbruch bei Zugriff auf STL vector Element. Warum?
-
BitShift schrieb:
ich habe einen Vektor mit Null terminierten Character-Strings (C-strings).
Du hast einen Vektor von Zeigern. Und die Zeiger zeigen auf unveränderliche Zeichenketten. Stell mal die Warnstufe hoch. Da müsste sowas kommen wie "Warnung: Implizite Konvertierung von Stringliteralen zu char* streicht const Qualifizierer" oder sowas. Das kommt daher, dass Stringliterale unveränderliche (const) Arrays sind und nur aus C-Kompatibilitäts-Gründen, diese Konvertierung zugelassen wird.
BitShift schrieb:
In der ersten Zeichenkette würde ich gerne den ersten Buchstaben ändern. Das Programm bricht an dieser Stelle mit einem Schreibfehler ab. Was mache ich falsch?
Du versuchst ein Zeichen eines Stringliterals zu verändern. Das ist falsch. Du verwendest char* wie eine Stringvariable. char* ist aber nur ein Zeigertyp und speichert die Zeichenkette gar nicht selbst. Dazu ist std::string da.
-
Ich habe den Fehler selbst gefunden. Ein Textliteral kann man natürlich nicht überschreiben. So geht's:
#include <vector> #include <iostream> using namespace std; int main( int argc, char** argv ) { char txt[5]={"text"}; vector<char*> vec; vec.push_back(txt); char *term = vec[0]; term[0] = 'T'; //Klappt return 0; }
-
Auch wenns geht ist es haesslich. Du solltest wirklich std::string verwenden.
-
krümelkacker schrieb:
BitShift schrieb:
ich habe einen Vektor mit Null terminierten Character-Strings (C-strings).
Du hast einen Vektor von Zeigern. Und die Zeiger zeigen auf unveränderliche Zeichenketten. Stell mal die Warnstufe hoch. Da müsste sowas kommen wie "Warnung: Implizite Konvertierung von Stringliteralen zu char* streicht const Qualifizierer" oder sowas. Das kommt daher, dass Stringliterale unveränderliche (const) Arrays sind und nur aus C-Kompatibilitäts-Gründen, diese Konvertierung zugelassen wird.
BitShift schrieb:
In der ersten Zeichenkette würde ich gerne den ersten Buchstaben ändern. Das Programm bricht an dieser Stelle mit einem Schreibfehler ab. Was mache ich falsch?
Du versuchst ein Zeichen eines Stringliterals zu verändern. Das ist falsch. Du verwendest char* wie eine Stringvariable. char* ist aber nur ein Zeigertyp und speichert die Zeichenkette gar nicht selbst. Dazu ist std::string da.
Vielen Dank für den Hinweis. Unsere Posts haben sich überschnitten. Das war der Fehler.
-
icarus2 schrieb:
Auch wenns geht ist es haesslich. Du solltest wirklich std::string verwenden.
Wenn ich könnte wie ich wollte würde ich auch gerne std:strings benutzen. Ich bin aber leider auf eine externe LIB angewiesen und die API schreibt einen Vektor mit C-Strings vor. Dumm gelaufen.

-
Du kannst dir einen entsprechenden C-String mit der .c_str() Methode vom std::string holen.
-
std::vector<char *> converted; converted.reserve(string_vector.size() ); for(size_t i=0; i<string_vector.size(); ++i) { converted.push_back(string_vector[i].c_str() ); }So kannst du erst mit strings arbeiten und dann in cstrings für die Lib konvertieren.
-
pyhax schrieb:
std::vector<char *> converted; converted.reserve(string_vector.size() ); for(size_t i=0; i<string_vector.size(); ++i) { converted.push_back(string_vector[i].c_str() ); }1. muss es vector<const char*> sein,
2. ist das mit std::transform ein Einzeiler
und 3. ist das mehr als unnötig.
-
include algorithm schrieb:
pyhax schrieb:
std::vector<char *> converted; converted.reserve(string_vector.size() ); for(size_t i=0; i<string_vector.size(); ++i) { converted.push_back(string_vector[i].c_str() ); }1. muss es vector<const char*> sein,
2. ist das mit std::transform ein Einzeiler
und 3. ist das mehr als unnötig.1./2. Hast du Recht, war nur so auf die schnelle hingeschrieben ...
3. Wieso unnötig?
-
3 ist nicht nur unnötig, sondern sogar potentiell Gefahr für Danling Pointers, falls einer der Strings neu allozieren muss.
-
Wie macht man es denn richtig? (Wenn man std::string verwenden will und die Lib)
-
Richtig wäre, bei jedem Aufruf .c_str() anzuhängen.
Lustig wäre, folgenden Wrapper zu verwenden:
template <typename Container> struct cstrings { cstrings(Container& c) : c(c){} const char* operator[](size_t at) const { return c[at].c_str(); } Container& c; }; typedef cstrings<std::vector<std::string> > cstring_vector; int main() { std::vector<std::string> string_vector = {"a", "b", "c"}; cstring_vector cstr(string_vector); puts(cstr[1]); }
-
Aber ich denke die Lib will einen std::vector haben
-
pyhax schrieb:
Aber ich denke die Lib will einen std::vector haben
Komisch. std vector und C-Strings?
-
pyhax schrieb:
Wie macht man es denn richtig? (Wenn man std::string verwenden will und die Lib)
Da bin ich jetzt auch mal gespannt, wie man hier wider die Lib programmieren soll.
-
Oder einen pointer?
-
Die Frage ist doch hauptsächlich, was die Lib mit der Sammlung von C-Strings anfängt und wie du vor und zwischen den Lib-Aufrufen die C-Strings erstellst/manipulierst. Je nachdem würde ich eine simple Wrapperklasse für C-Strings schreiben, einen Container, der die Dinger verwaltet, und eine Möglichkeit, aus dem Container den benötigten std::vector<char*> zu holen.
-
pumuckl schrieb:
Die Frage ist doch hauptsächlich, was die Lib mit der Sammlung von C-Strings anfängt [...]

Falls die Lib-Schnittstelle wirklich so aussieht:
void irgendeine_lib_funktion(vector<char*> const& param);und sich diese Funktion die Zeiger weder "irgendwo anders" über den Funktionsaufruf hinaus speichert, noch über sie die Zeichenketten ändern will, dann würde ich wahrscheinlich auch temporär einen solchen Vektor anlegen und ihn per reinterpret_cast mit Zeigern befüllen, die ich über string::c_str von string-Objekten bekomme, die lang genug leben. Das ist zwar unschön, aber was soll man auch groß anders machen, mit so einer Schnittstelle?
Dass dann in einer Klasse zu kapseln, wie Pumuckl vorschlägt, klingt auch nicht doof.
-
krümelkacker schrieb:
....reinterpret_cast mit Zeigern befüllen, die ich über string::c_str von string-Objekten bekomme, die lang genug leben.
Jo, das deren Destruktor dann selbstverständliche Sachen macht...
Wenn mich aber nicht alles täuscht, nimmt man da nicht const_cast (oder ich kapier nich' was du machen willst)?