2010-03-05 2 views
6

Я застреваю в проблеме printf. Я был бы признателен, если бы я мог получить помощь здесь: В приведенном ниже коде я вижу, что семейство шрифтов правильно перемещается в first printf(), , но если я задаю его переменной, я получаю только пустую строку. Как я могу поместить его в переменную и иметь правильные значения? Я просто не хочу набирать 'font.family(). Family(). String(). Utf8(). Data()' всюду?printf вопрос с константой char * переменная

Я сделал это в тот же метод:

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

и подписью 'данных()' является

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

} 

Подпись utf8() является

class String { 
CString utf8() const; 
} 

Спасибо.

+0

Что это за библиотека шрифтов? C++ не имеет такой вещи. Возможно, попробуйте включить тип, возвращаемый 'data()'. С другой стороны, любая причина не использовать 'std :: string' /' std :: cout'? – GManNickG

+1

Это поможет узнать подписи метода '.data()'. – pioto

+0

И family.string() возвращает временный объект типа CString? –

ответ

4

Что-то в цепи font.family().family().string().utf8().data() возвращает временный объект. В вашем первом printf временный объект не выходит за пределы области действия до тех пор, пока не вернется printf. Во втором printf временное уничтожено после назначения указателя, и указатель теперь недействителен. Вы видите классический пример «неопределенного поведения».

Есть два способа исправить это. Либо сделайте копию данных до временного уничтожения, либо сделайте ссылку на временную. Копия, вероятно, самая простая и ясная, если у класса есть оператор копирования. Если предположить, что utf8() генерирует временный CString, это было бы

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

Это неправильно. Временами гарантируется, что они будут стоять так долго, как нужно (более или менее). – 2010-03-05 21:55:12

+0

Ссылка на временное гарантируется, но указатель на некоторый внутренний элемент данных? Думаю, нет. –

+0

В цитируемом коде нет указателей. «Внутренние» указатели будут рассмотрены механизмом конструктора/деструктора C++. – 2010-03-05 21:58:15

0

Призыв к data() (предполагая, что она вызывается на станд :: строка) не обязательно возвращает строку с завершающим нулем. Вы почти наверняка хотите c_str(), который определен для этого.

1

Вы кешируете указатель, который находится во временном порядке, возвращаемом utf8() (как утверждали Марк и Нейл). Вам нужно будет изменить fontFamily на CString или const CString &, чтобы сохранить результат от utf8() в области.

+0

Спасибо. Это устраняет проблему. – michael

Смежные вопросы