Ist es sicher, die Methoden eines temporären Objekts aufzurufen?

7

Ich habe eine Funktion, die ein char * zurückgeben soll. Da ich einige Strings verketten muss, habe ich folgende Zeile geschrieben:

%Vor%

Ich weiß, dass ich die Frage vermeiden könnte, die den String benennt, den ich verwenden möchte. Ich möchte nur die Chance nutzen, eine allgemeinere Frage zu stellen: Ist es sicher, Methoden temporärer Variablen aufzurufen? ist es standardkonform?

    
Emiliano 31.03.2009, 14:43
quelle

4 Antworten

12

Es ist sicher, Methoden temporärer Variablen aufzurufen, aber nicht sicher, ein char * einer temporären Variablen zur späteren Verwendung zurückzugeben.

Dieses Zeichen * zeigt auf einen Puffer, der bald freigegeben wird. Sobald es freigegeben ist, haben Sie einen Zeiger auf eine ungültige Region im Speicher.

Liefern Sie stattdessen ein std :: string-Objekt.

    
Brian R. Bondy 31.03.2009, 14:45
quelle
6

Sie dürfen Methoden auf Provisorien aufrufen, Sie müssen jedoch vorsichtig mit Objektlebensdauern sein - insbesondere, wenn Sie eine Funktion haben, die c_str() aufgerufen für eine temporäre std::string zurückgibt, wird dieses Zeichenfolgenobjekt zerstört wenn die Funktion zurückkehrt.

Ihr Code oben leidet unter diesem Problem.

    
j_random_hacker 31.03.2009 14:48
quelle
4

Die C-Zeichenfolge, die durch Aufrufen von c_str () auf dem temporären zurückgegeben wird, wird gültig sein, bis der nächste Aufruf von c_str () auf dem temporären, das nie passieren kann. Das temporäre selbst bleibt bis zum Ende des vollständigen Ausdrucks (der return-Anweisung) hängen.

Wenn Sie eine std :: string zurückgeben würden, wäre alles hunkydory, da der Kopierkonstruktor der Zeichenfolge in der Rückkehr aufgerufen würde, um eine Kopie zu erstellen. Wenn Sie ein Char * zurückgeben, sind alle Wetten deaktiviert, da der Wert, den Sie zurückgeben, beim Verlassen der Funktion entsorgt wird. Dies hat nichts speziell mit dem temporären zu tun, es ist ein allgemeines Problem beim Zurückgeben von char * - ziehen Sie stattdessen lieber std :: strings zurück.

    
anon 31.03.2009 14:51
quelle
1

Ein generierter Zeiger wird solange gut sein, wie das temporäre noch vorhanden ist, normalerweise bis zum Ende des Ausdrucks. Die Ausnahmen sind, wenn ein temporäres Objekt in einem Initialisierer verwendet wird (in diesem Fall dauert es so lange, bis die Initialisierung beendet ist) oder wenn es an einen Verweis gebunden ist. Ein temporäres in einer Funktion return-Anweisung dauert, bis die Funktion beendet wird (sofern sie nicht an eine Referenz gebunden ist). Sobald die vorübergehende Lebenszeit vorüber ist, wird das Temporäre zerstört. In diesem Fall bedeutet dies, dass der String-Destruktor ausgeführt wird und daher der Speicher für die Zeichen freigegeben wird. Mit anderen Worten, sobald der Wert zurückgegeben wird, ist es garantiert ungültig.

Sie könnten die Zeichenfolge selbst zurückgeben und als konstante Referenz zurückgeben. Sie könnten die .c_str () in den neu zugewiesenen Speicher kopieren und diesen (als Zeiger oder Smart-Zeiger) zurückgeben. Einer von denen würde funktionieren.

Die Lebensdauer von Provisorien wird in Abschnitt 12.2 des C ++ - Standards behandelt. Gemäß dem Standard geben Sie einen Zeiger auf freigegebenen Speicher zurück.

    
David Thornley 31.03.2009 15:02
quelle

Tags und Links