Meine übergeordnete Anwendung befasst sich nur mit std::stringalso dachte ich an die Verwendung std::string::c_str() zurück zu bekommen const char* Zeiger.
Aber was ist die Lebensdauer von c_str() ?
Kann ich so etwas tun, ohne mit undefiniertem Verhalten konfrontiert zu werden?
{
std::string server = "my_server";
std::string name = "my_name";
Foo foo;
foo.server = server.c_str();
foo.name = name.c_str();
// We use foo
use_foo(foo);
// Foo is about to be destroyed, before name and server
}
Oder soll ich das Ergebnis gleich kopieren c_str() an einen anderen Ort?
Danke.
Ist mir passiert, als ich eine lokale Zeichenfolge in einer Funktion definiert und zurückgegeben habe .c_str(). Ich habe nicht verstanden, warum ich manchmal nur Teile der Zeichenfolge bekomme, bis ich verstanden habe, dass die const char* lebt nicht ewig, sondern bis die Saite zerstört wird
– Etwas etwas
2. Dezember 2014 um 17:34 Uhr
Christoph Johnson
Die c_str() Ergebnis wird ungültig, wenn die std::string zerstört wird oder wenn eine nicht konstante Elementfunktion der Zeichenfolge aufgerufen wird. Normalerweise möchten Sie also eine Kopie davon erstellen, wenn Sie sie aufbewahren müssen.
Im Fall Ihres Beispiels scheinen die Ergebnisse von c_str() werden sicher verwendet, da die Zeichenfolgen in diesem Bereich nicht geändert werden. (Allerdings wissen wir nicht, was use_foo() oder ~Foo() könnte mit diesen Werten zu tun haben; Wenn sie die Zeichenfolgen an eine andere Stelle kopieren, sollten sie ein wahres tun Kopierenund nicht nur kopieren char Zeiger.)
Der c_str()-Zeiger könnte ungültig sein, wenn das std::string-Objekt ein automatisches Objekt ist, das den Gültigkeitsbereich verlässt oder eine Thread-Erstellungsfunktion aufruft.
– GuruM
16. Oktober 2012 um 15:49 Uhr
Kannst du bitte Erklären non-const member function of the string is called.?
– Mathew Kurian
24. Dezember 2013 um 11:03 Uhr
Eine “nicht konstante Member-Funktion” ist jede Member-Funktion, die nicht mit gekennzeichnet ist const Stichwort. Eine solche Funktion könnte den Inhalt des Strings ändern, in diesem Fall muss der String möglicherweise den Speicher für die nullterminierte Version des zurückgegebenen Strings neu zuweisen c_str(). Zum Beispiel, size() und length() sind constsodass Sie sie aufrufen können, ohne sich Gedanken über die Änderung der Zeichenfolge machen zu müssen, aber clear() ist nicht const.
– Christoph Johnson
24. Dezember 2013 um 20:16 Uhr
Technisch ist Ihr Code in Ordnung.
ABER Sie haben so geschrieben, dass es für jemanden, der den Code nicht kennt, leicht zu knacken ist. Für c_str() ist die einzige sichere Verwendung, wenn Sie es als Parameter an eine Funktion übergeben. Sonst öffnen Sie sich Wartungsproblemen.
Beispiel 1:
{
std::string server = "my_server";
std::string name = "my_name";
Foo foo;
foo.server = server.c_str();
foo.name = name.c_str();
//
// Imagine this is a long function
// Now a maintainer can easily come along and see name and server
// and would never expect that these values need to be maintained as
// const values so why not re-use them
name += "Martin";
// Oops now its broken.
// We use foo
use_foo(foo);
// Foo is about to be destroyed, before name and server
}
Machen Sie es also für die Wartung offensichtlich:
Bessere Lösung:
{
// Now they can't be changed.
std::string const server = "my_server";
std::string const name = "my_name";
Foo foo;
foo.server = server.c_str();
foo.name = name.c_str();
use_foo(foo);
}
Aber wenn Sie konstante Zeichenfolgen haben, brauchen Sie sie nicht wirklich:
OK. Aus irgendeinem Grund möchten Sie sie als Zeichenfolgen:
Warum nicht nur im Anruf verwenden:
{
std::string server = "my_server";
std::string name = "my_name";
// guaranteed not to be modified now!!!
use_foo(Foo(server.c_str(), name.c_str());
}
Es ist gültig, bis einer der folgenden Fälle mit dem entsprechenden passiert string Objekt:
das Objekt wird zerstört
Das Objekt wird geändert
Sie sind mit Ihrem Code einverstanden, es sei denn, Sie ändern diese string Gegenstände nach c_str()s hineinkopiert werden foo Aber vorher use_foo() wird genannt.
Die const char* zurückgekehrt von c_str() gilt nur bis zum nächsten nicht konstanten Aufruf an die std::string Objekt. In diesem Fall sind Sie in Ordnung, weil Ihr std::string ist noch im Geltungsbereich für die Lebensdauer von Foo und Sie führen keine anderen Operationen durch, die die Zeichenfolge ändern würden, während Sie foo verwenden.
Solange der String nicht zerstört oder modifiziert wird, ist die Verwendung von c_str() in Ordnung. Wenn die Zeichenfolge mit einem zuvor zurückgegebenen c_str() modifiziert wird, ist die Implementierung definiert.
Ist mir passiert, als ich eine lokale Zeichenfolge in einer Funktion definiert und zurückgegeben habe
.c_str()
. Ich habe nicht verstanden, warum ich manchmal nur Teile der Zeichenfolge bekomme, bis ich verstanden habe, dass dieconst char*
lebt nicht ewig, sondern bis die Saite zerstört wird– Etwas etwas
2. Dezember 2014 um 17:34 Uhr