2012-04-04 13 views
45

Ist der folgende C++ Code wohlgeformt:std :: string :: c_str() und Provisorien

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 habe ich mit ihm ist, dass nach dem temporären std :: string-Objekt erstellen und unter der Zeiger c_str(), nichts verhindert, dass das std :: string-Objekt zerstört wird (oder vielleicht liege ich falsch?). Kannst du mich bitte auf den Standard hinweisen, wenn der Code trotz allem OK ist. Es funktioniert, wenn ich mit g ++ teste.

Antwort

56

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

Die Lebensdauer von Provisorien wurde seit C++ 98 streng definiert. Davor variierte es, abhängig vom Compiler, und der Code, den Sie geschrieben haben, hätte nicht mit g ++ gearbeitet (vor 1995, ungefähr — g ++ änderte dies fast sofort, als das Standardkomitee es wählte). (Es gab keine std::string dann entweder, aber die gleichen Probleme betreffen eine beliebige geschriebene String-Klasse.)

18

Die temporäre std::string ‚s Lebensdauer über den Punkt hinaus erstreckt gerade dort, wo consumer zurückkehrt, so dass es sicher ist direkt aus consumer auf dieser Zeichenfolge etwas zu verwenden. Was ist nicht OK ist, um den Wert c_str zurückgibt und versuchen, es später zu verwenden (das temporäre wurde zerstört, und wir können nur erraten, was Sie am anderen Ende des Zeigers finden werden).

+1

können Sie einen Hinweis in Bezug auf die C++ 03 oder die C++ 11 Standard bitte geben? – user1095108

+3

Die Lebensdauer eines Temporären ist in §12.2 definiert. (Abschnitt 12 ist mit dem Titel "Special Member-Funktionen", die nicht genau dort ist, wo Sie erwarten würden, für die Lebensdauer der Provisorien zu suchen, aber das ist, wo es ist.) –

+0

@ user1095108 und Lebensdauer der Funktion Argumente können aus § erhalten werden 3.2.2 und §3.7.2 in der C++ 03 Standard. – juanchopanza

5

Das temporäre von der Funktion random_string_generator() zurückgegebene kann in Consumer() Funktion sicher verwendet werden.

Verwandte Themen