2016-09-06 3 views
4

Betrachten Sie den folgenden Code, basierend auf this answer:Temporär in einem Funktionsaufruf: UB?

#include <iostream> 
#include <sstream> 

class StringBuilder { 
public: 
    template <typename T> inline StringBuilder &operator<<(T const &t) { 
     ss << t; 
     return *this; 
    } 

    inline char const * c_str() { 
     return ss.str().c_str(); 
    } 

private: 
    std::stringstream ss; 
}; 

void foo(const char *x) { 
    std::cout << x << std::endl; 
} 

int main() { 
    foo((StringBuilder() << "testing " << 12 << 3 << 4).c_str()); 
    return 0; 
} 

Hat foo() mit der temporären StringBuilder ‚s Rückgabewert Ursache UB in irgendeiner Weise nennen?

Der Grund, warum ich frage ist, dass das obige Beispiel funktioniert, aber im wirklichen Leben benutze ich eine Bibliothek, die unter anderem Protokollierungsmöglichkeiten enthält, und mit dieser Bibliothek bekomme ich falsche Ausgabe (die Logging-Funktion nimmt meine char* richtig, aber überschreibt es intern, was mich dazu gebracht hat zu glauben, dass der Speicher nicht mehr gültig ist).

+1

Sie haben UB in 'return ss.str(). C_str();' Siehe: http://stackoverflow.com/questions/21034834/is-there-issue-will-stringstream-str-c-str – Hayt

Antwort

7

Ja, aber nicht wegen dem, was Sie vielleicht denken.

Die temporäre StringBuilder im Funktionsaufruf wird nicht zerstört, bis nach foo zurückkommt, so dass es in Ordnung ist.

jedoch die c_str() Methode gibt das Ergebnis des Aufrufs .str().c_str() und die temporäre Zeichenfolge, die durch diese str() zurückgegeben wird als StringBuilder::c_str() kehrt zerstört, was bedeutet, dass der zurückgegebene Zeiger ungültig außen. Die Verwendung dieses Zeigers verursacht UB.

+0

Danke, das macht Sinn, ich habe den Punkt übersehen, dass 'stringstream :: str()' den String als Kopie zurückgegeben hat. Gibt es eine Möglichkeit, meinen 'StringBuilder' zu reparieren, außer das' ss.str() '' s Ergebnis in einen anderen 'String' in meiner Klasse zu kopieren oder' '(StringBuilder() << 1) .str(). C_str () '? – rainer

+0

Warum sagt [das] (http://stackoverflow.com/questions/10006891/stdstringc-str-and-timporaries) das Gegenteil? Warum gibt es hier zwei gelöschte Antworten? – LogicStuff

+0

@LogicStuff Die verknüpfte Frage ist anders, weil in dieser Situation die temporäre 'std :: string' nicht zerstört wird, bevor der Zeiger verwendet wird. Und ich kann nur über die zwei gelöschten Antworten raten, aber da sie beide gepostet und gelöscht wurden, während ich meine schrieb, würde ich vermuten, dass sie nur die Zeile in 'main' angeschaut haben, nichts falsch daran gesehen haben, und dann ihre gelöscht haben Antworten, nachdem ich 'Hayts' Kommentar gesehen habe (der auch während ich meine Antwort geschrieben habe und das Kernproblem enthält). –

Verwandte Themen