std::string::c_str() und Temporäre

Lesezeit: 3 Minuten

Ist der folgende C++-Code wohlgeformt:

void consumer(char const* p)
{
  std::printf("%s", p);
}

std::string random_string_generator()
{
  // returns a random std::string object
}

consumer(random_string_generator().c_str());

Das Problem, das ich damit habe, ist, dass nach dem Erstellen des temporären std::string-Objekts und dem Nehmen des c_str()-Zeigers nichts verhindert, dass das std::string-Objekt zerstört wird (oder liege ich falsch?). Kannst du mich bitte auf den Standard hinweisen, ob der Code trotz allem ok ist. Es funktioniert, wenn ich mit g ++ teste.

Der von zurückgegebene Zeiger std::string::c_str() zeigt auf Speicher, der vom String-Objekt verwaltet wird. Es bleibt gültig, bis eine nicht konstante Funktion für das Zeichenfolgenobjekt aufgerufen wird oder das Zeichenfolgenobjekt zerstört wird. Das String-Objekt, um das Sie sich Sorgen machen, ist ein temporäres Objekt. Es wird am Ende des vollständigen Ausdrucks zerstört, nicht davor und nicht danach. In Ihrem Fall steht das Ende des vollständigen Ausdrucks nach dem Aufruf von to consumer, damit Ihr Code sicher ist. Es wäre nicht wenn consumer
den Zeiger irgendwo gespeichert, mit der Idee, ihn später zu verwenden.

Die Lebensdauer von Temporären ist seit C++98 streng definiert. Davor war es je nach Compiler unterschiedlich, und der von Ihnen geschriebene Code hätte mit g++ nicht funktioniert (ungefähr vor 1995 – g++ änderte dies fast sofort, als das Standardkomitee darüber abstimmte). (Es gab keine std::string dann entweder, aber die gleichen Probleme betreffen jede vom Benutzer geschriebene Zeichenfolgenklasse.)

  • was wäre, wenn man die benutzt c_str() const char* in einer nachfolgenden Anweisung (immer noch innerhalb der Funktion, aber außerhalb der ersten Anweisung)? Würde uns das einen baumelnden Zeiger bringen?

    – Alex Gidan

    20. Februar 2019 um 16:04 Uhr


  • Ich antworte mir selbst … In diesem Fall wäre es ungültig: § 12.2 … Temporäre Objekte werden als letzter Schritt bei der Auswertung des Vollausdrucks (1.9) zerstört, der (lexikalisch) den Punkt enthält, an dem sie erzeugt wurden. Dies gilt auch dann, wenn diese Auswertung mit dem Auslösen einer Ausnahme endet.

    – Alex Gidan

    20. Februar 2019 um 16:53 Uhr

  • std::string temp = random_string_generator().c_str(); Ist es richtig anzunehmen, dass die Temperatur korrekt ist? da die Lebensdauer der von random_string_generator() zurückgegebenen Zeichenfolge bis zum Ende des Ausdrucks sein wird?

    – Ayush-Hose

    17. Juni 2021 um 20:44 Uhr


Das Temporäre std::string‘s Lebensdauer reicht nur über den Punkt hinaus, an dem consumer zurückgibt, so dass es sicher ist, alles auf dieser Zeichenfolge zu verwenden direkt von innen consumer. Was ist nicht OK ist, den Wert zu speichern c_str zurück und versuchen Sie es später zu verwenden (das Temporär wurde zerstört, und wir können nur raten, was Sie am anderen Ende des Zeigers finden werden).

  • Können Sie bitte einen Hinweis zum C++03- oder C++11-Standard geben?

    – Benutzer1095108

    4. April 2012 um 7:53 Uhr

  • Die Lebensdauer eines Provisoriums ist in §12.2 definiert. (Abschnitt 12 trägt den Titel „Spezielle Mitgliederfunktionen“, was nicht genau der Ort ist, an dem Sie nach der Lebensdauer von Provisorien suchen würden, aber genau dort ist es.)

    – James Kanze

    4. April 2012 um 7:56 Uhr

  • @user1095108 und die Lebensdauer von Funktionsargumenten können aus §3.2.2 und §3.7.2 im c++03-Standard abgerufen werden.

    – Juanchopanza

    4. April 2012 um 8:24 Uhr

Das von der Funktion random_string_generator() zurückgegebene Temporär kann sicher in der Consumer()-Funktion verwendet werden.

885700cookie-checkstd::string::c_str() und Temporäre

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy