2010-03-05 12 views
6

Ich bin in einem printf Problem stecken. Ich würde schätzen, wenn ich hier etwas Hilfe bekommen kann: Im folgenden Code kann ich sehen, dass die Schriftfamilie im ersten printf(), richtig verschoben wird, aber wenn ich es auf Variable setze, erhalte ich nur eine leere Zeichenkette. Wie kann ich es in eine Variable setzen und die richtigen Werte haben? Ich will nur nicht 'font.family(). Family(). String(). Utf8(). Data()' überall?printf Frage mit einer const Char * Variable

Ich tat dies in der gleichen Methode:

void myMethod() { 
     const char* fontFamily = font.family().family().string().utf8().data(); 
     // get displayed correctly 
     printf ("drawText1 %s \n", font.family().family().string().utf8().data()); 
     // get an empty string 
     printf ("drawText2 %s \n", fontFamily); 
} 

und die Unterschrift von 'Daten()' ist

class CString { 
public: 
    CString() { } 
    CString(const char*); 
    CString(const char*, unsigned length); 
    CString(CStringBuffer* buffer) : m_buffer(buffer) { } 
    static CString newUninitialized(size_t length, char*& characterBuffer); 

    const char* data() const; 
//... 

} 

Die Unterschrift von UTF-8() ist

class String { 
CString utf8() const; 
} 

Vielen Dank.

+0

Was ist diese Schriftbibliothek? C++ hat so etwas nicht. Versuchen Sie vielleicht, den von 'data()' zurückgegebenen Typ zu verwenden. Nebenbei, irgendein Grund, nicht 'std :: string' /' std :: cout' zu verwenden? – GManNickG

+1

Es würde helfen, die Signatur der '.data()' Methode zu kennen. – pioto

+0

Und family.string() gibt ein temporäres Objekt vom Typ CString zurück? –

Antwort

4

Etwas in der Kette von font.family().family().string().utf8().data() gibt ein temporäres Objekt zurück. In Ihrer ersten printf, das temporäre Objekt nicht außerhalb des Geltungsbereichs, bis die printf zurückgibt. In der zweiten printf wurde das temporäre nach der Zeigerzuweisung zerstört, und der Zeiger ist jetzt ungültig. Sie sehen ein klassisches Beispiel für "undefiniertes Verhalten".

Es gibt zwei Möglichkeiten, dies zu beheben. Erstellen Sie entweder eine Kopie der Daten, bevor das temporäre Objekt zerstört wird, oder erstellen Sie einen Verweis auf das temporäre Objekt. Die Kopie ist wahrscheinlich am einfachsten und am klarsten, solange die Klasse einen Kopieroperator hat. Unter der Annahme, dass utf8() ein temporäres CString erzeugt, würde dies

seine
CString fontFamily = font.family().family().string().utf8(); 
printf ("drawText2 %s \n", fontFamily.data()); 
+0

Das ist falsch. Provisorien sind garantiert so lange wie nötig (mehr oder weniger). –

+0

Ein Verweis auf ein temporäres ist garantiert, aber ein Zeiger auf ein internes Datenelement? Ich denke nicht. –

+0

Es gibt keine Zeiger im zitierten Code. "Interne" Zeiger werden vom C++ - Konstruktor/Destruktor-Mechanismus behandelt. –

0

Der Aufruf von data() (vorausgesetzt, es auf einem std :: string genannt wird) kehrt nicht unbedingt einen nullterminierten String. Sie wollen fast sicher c_str(), was definiert ist, dies zu tun.

1

Sie zwischenspeichern einen Zeiger, der in dem temporären von utf8() zurückgegeben wird (wie Mark und Neil argumentiert haben). Sie müssen fontFamily entweder in CString oder const CString & ändern, um das Ergebnis von utf8() im Geltungsbereich zu behalten.

+0

Danke. Dies behebt das Problem. – michael