2010-03-05 24 views
6

Estoy atascado en un problema de printf. Agradecería si pudiera obtener ayuda aquí: En el siguiente código, puedo ver que la familia de fuentes se desplazó correctamente en la primera impresión(), , pero si configuro la variable, solo obtengo una cadena vacía. ¿Cómo puedo ponerlo en una variable y tener los valores correctos? Simplemente no quiero escribir 'font.family(). Family(). String(). Utf8(). Data()' everywhere?printf pregunta con una variable const char *

hice esto en el mismo método:

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); 
} 

y la firma de 'datos()' es

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; 
//... 

} 

La firma de UTF-8() es

class String { 
CString utf8() const; 
} 

Gracias.

+0

¿Qué es esta biblioteca de fuentes? C++ no tiene tal cosa. Tal vez intente incluir el tipo devuelto por 'data()'. En una nota lateral, ¿hay alguna razón para no usar 'std :: string' /' std :: cout'? – GManNickG

+1

Sería útil conocer la firma del método '.data()'. – pioto

+0

Y family.string() devuelve un objeto temporal de tipo CString? –

Respuesta

4

Algo en la cadena de font.family().family().string().utf8().data() está devolviendo un objeto temporal. En su primer printf, el objeto temporal no sale del ámbito hasta que devuelva el printf. En el segundo printf, el temporal se ha destruido después de que se realizó la asignación del puntero, y el puntero ahora no es válido. Estás viendo un ejemplo clásico de "comportamiento indefinido".

Hay dos formas de arreglar esto. Haga una copia de los datos antes de que se destruya el temporal o haga una referencia al temporal. La copia es probablemente la más fácil y clara, siempre que la clase tenga un operador de copia. Suponiendo que utf8() genera temporal CString, sería

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

Esto está mal. Los temporarios están garantizados para quedarse tanto tiempo como sea necesario (más o menos). –

+0

¿Está garantizada la referencia a un temporal, pero un puntero a algún miembro de datos interno? Yo creo que no. –

+0

No hay punteros en el código entre comillas. Los punteros "internos" serán atendidos por el mecanismo constructor/destructor de C++. –

0

El llamada data() (asumirla llama un std :: string) no necesariamente devolver cadena terminada. Es casi seguro que desee c_str(), que está definido para hacerlo.

1

Está almacenando en caché un puntero que reside en el temporal devuelto por utf8() (como Mark y Neil han discutido). Tendrá que cambiar fontFamily a CString o const CString & para mantener el resultado de utf8() en el alcance.

+0

Gracias. Esto soluciona el problema. – michael