In einem meiner Programme muss ich mit einem Legacy-Code arbeiten, mit dem funktioniert const char*
.
Nehmen wir an, ich habe eine Struktur, die so aussieht:
struct Foo
{
const char* server;
const char* name;
};
Meine übergeordnete Anwendung befasst sich nur mit std::string
, daher habe ich darüber nachgedacht std::string::c_str()
, const char*
Zeiger zurückzugewinnen.
Aber wie lange dauert es c_str()
?
Kann ich so etwas tun, ohne mich einem undefinierten Verhalten zu stellen?
{
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 sofort c_str()
an einen anderen Ort kopieren ?
Danke dir.
.c_str()
. Ich habe nicht verstanden, warum ich manchmal nur Teile der Saite bekomme, bis ich verstanden habe, dass dieconst char*
nicht für immer lebt, sondern bis die Saite zerstört istAntworten:
Das
c_str()
Ergebnis wird ungültig, wenn dasstd::string
zerstört wird oder wenn eine nicht konstante Mitgliedsfunktion der Zeichenfolge aufgerufen wird. Normalerweise möchten Sie also eine Kopie davon erstellen, wenn Sie sie behalten müssen.In Ihrem Beispiel werden die Ergebnisse von
c_str()
sicher verwendet, da die Zeichenfolgen in diesem Bereich nicht geändert werden. (Wir wissen jedoch nicht, wasuse_foo()
oder~Foo()
was mit diesen Werten geschehen könnte. Wenn sie die Zeichenfolgen an anderer Stelle kopieren , sollten sie eine echte Kopie erstellen und nicht nur diechar
Zeiger kopieren .)quelle
non-const member function of the string is called.
?const
Schlüsselwort gekennzeichnet ist. Eine solche Funktion kann den Inhalt der Zeichenfolge mutieren. In diesem Fall muss die Zeichenfolge möglicherweise den Speicher für die nullterminierte Version der von zurückgegebenen Zeichenfolge neu zuweisenc_str()
. Zum Beispielsize()
undlength()
sindconst
, so dass Sie sie aufrufen können, ohne sich Gedanken über die Änderung der Zeichenfolge machen zu müssen, diesclear()
ist jedoch nicht der Fallconst
.Technisch ist Ihr Code in Ordnung.
ABER Sie haben so geschrieben, dass es für jemanden, der den Code nicht kennt, leicht zu brechen ist. Für c_str () ist die einzige sichere Verwendung, wenn Sie es als Parameter an eine Funktion übergeben. Ansonsten öffnen Sie sich für Wartungsprobleme.
Beispiel 1:
Machen Sie zur Wartung Folgendes klar:
Bessere Lösung:
Aber wenn Sie const Strings haben, brauchen Sie sie eigentlich nicht:
OK. Aus irgendeinem Grund möchten Sie sie als Zeichenfolgen:
Warum nicht nur im Aufruf verwenden:
quelle
Es ist gültig, bis eine der folgenden Aktionen mit dem entsprechenden
string
Objekt ausgeführt wird:Ihr Code ist in Ordnung, es sei denn, Sie ändern diese
string
Objekte, nachdemc_str()
s in sie kopiert wurde,foo
aber bevor sieuse_foo()
aufgerufen werden.quelle
Der Rückgabewert von c_str () ist nur bis zum nächsten Aufruf einer nicht konstanten Mitgliedsfunktion für dieselbe Zeichenfolge gültig
quelle
Die
const char*
Rückgabe vonc_str()
ist nur bis zum nächsten nicht konstanten Aufruf desstd::string
Objekts gültig . In diesem Fall geht es Ihnen gut, da Siestd::string
noch ein Leben lang in ReichweiteFoo
sind und Sie keine anderen Vorgänge ausführen, die die Zeichenfolge bei Verwendung von foo ändern würden.quelle
Solange die Zeichenfolge nicht zerstört oder geändert wird, ist die Verwendung von c_str () in Ordnung. Wenn der String mit einem zuvor zurückgegebenen c_str () geändert wird, ist die Implementierung definiert.
quelle
Der Vollständigkeit halber hier eine Referenz und ein Zitat von cppreference.com :
quelle